diff --git a/Changelog b/Changelog deleted file mode 100644 index 5d59a9738d..0000000000 --- a/Changelog +++ /dev/null @@ -1,1054 +0,0 @@ -Entries are sorted chronologically from oldest to youngest within each release, -releases are sorted from youngest to oldest. - -version : - - -version 1.1: - -- stream disposition information printing in ffprobe -- filter for loudness analysis following EBU R128 -- Opus encoder using libopus -- ffprobe -select_streams option -- Pinnacle TARGA CineWave YUV16 decoder -- TAK demuxer, decoder and parser -- DTS-HD demuxer -- remove -same_quant, it hasn't worked for years -- FFM2 support -- X-Face image encoder and decoder -- 24-bit FLAC encoding -- multi-channel ALAC encoding up to 7.1 -- metadata (INFO tag) support in WAV muxer -- subtitles raw text decoder -- support for building DLLs using MSVC -- LVF demuxer -- ffescape tool -- metadata (info chunk) support in CAF muxer -- field filter ported from libmpcodecs -- AVR demuxer -- geq filter ported from libmpcodecs -- remove ffserver daemon mode -- AST muxer/demuxer -- new expansion syntax for drawtext -- BRender PIX image decoder -- ffprobe -show_entries option -- ffprobe -sections option -- ADPCM IMA Dialogic decoder -- BRSTM demuxer -- animated GIF decoder and demuxer -- PVF demuxer -- subtitles filter -- IRCAM muxer/demuxer -- Paris Audio File demuxer -- Virtual concatenation demuxer -- VobSub demuxer -- JSON captions for TED talks decoding support -- SOX Resampler support in libswresample -- aselect filter -- SGI RLE 8-bit decoder -- Silicon Graphics Motion Video Compressor 1 & 2 decoder -- Silicon Graphics Movie demuxer -- apad filter -- Resolution & pixel format change support with multithreading for H.264 -- documentation split into per-component manuals -- pp (postproc) filter ported from MPlayer -- NIST Sphere demuxer -- MPL2, VPlayer, MPlayer, AQTitle, PJS and SubViewer v1 subtitles demuxers and decoders -- Sony Wave64 muxer -- adobe and limelight publisher authentication in RTMP -- data: URI scheme -- support building on the Plan 9 operating system -- kerndeint filter ported from MPlayer -- histeq filter ported from VirtualDub -- 012v decoder - - -version 1.0: - -- INI and flat output in ffprobe -- Scene detection in libavfilter -- Indeo Audio decoder -- channelsplit audio filter -- setnsamples audio filter -- atempo filter -- ffprobe -show_data option -- RTMPT protocol support -- iLBC encoding/decoding via libilbc -- Microsoft Screen 1 decoder -- join audio filter -- audio channel mapping filter -- Microsoft ATC Screen decoder -- RTSP listen mode -- TechSmith Screen Codec 2 decoder -- AAC encoding via libfdk-aac -- Microsoft Expression Encoder Screen decoder -- RTMPS protocol support -- RTMPTS protocol support -- RTMPE protocol support -- RTMPTE protocol support -- showwaves and showspectrum filter -- LucasArts SMUSH playback support -- SAMI, RealText and SubViewer demuxers and decoders -- Heart Of Darkness PAF playback support -- iec61883 device -- asettb filter -- new option: -progress -- 3GPP Timed Text encoder/decoder -- GeoTIFF decoder support -- ffmpeg -(no)stdin option -- Opus decoder using libopus -- caca output device using libcaca -- alphaextract and alphamerge filters -- concat filter -- flite filter -- Canopus Lossless Codec decoder -- bitmap subtitles in filters (experimental and temporary) -- MP2 encoding via TwoLAME -- bmp parser -- smptebars source -- asetpts filter -- hue filter -- ICO muxer -- SubRip encoder and decoder without embedded timing -- edge detection filter -- framestep filter -- ffmpeg -shortest option is now per-output file - -pass and -passlogfile are now per-output stream -- volume measurement filter -- Ut Video encoder -- Microsoft Screen 2 decoder -- smartblur filter ported from MPlayer -- CPiA decoder -- decimate filter ported from MPlayer -- RTP depacketization of JPEG -- Smooth Streaming live segmenter muxer -- F4V muxer -- sendcmd and asendcmd filters -- WebVTT demuxer and decoder (simple tags supported) -- RTP packetization of JPEG -- faststart option in the MOV/MP4 muxer -- support for building with MSVC - - -version 0.11: - -- Fixes: CVE-2012-2772, CVE-2012-2774, CVE-2012-2775, CVE-2012-2776, CVE-2012-2777, - CVE-2012-2779, CVE-2012-2782, CVE-2012-2783, CVE-2012-2784, CVE-2012-2785, - CVE-2012-2786, CVE-2012-2787, CVE-2012-2788, CVE-2012-2789, CVE-2012-2790, - CVE-2012-2791, CVE-2012-2792, CVE-2012-2793, CVE-2012-2794, CVE-2012-2795, - CVE-2012-2796, CVE-2012-2797, CVE-2012-2798, CVE-2012-2799, CVE-2012-2800, - CVE-2012-2801, CVE-2012-2802, CVE-2012-2803, CVE-2012-2804, -- v408 Quicktime and Microsoft AYUV Uncompressed 4:4:4:4 encoder and decoder -- setfield filter -- CDXL demuxer and decoder -- Apple ProRes encoder -- ffprobe -count_packets and -count_frames options -- Sun Rasterfile Encoder -- ID3v2 attached pictures reading and writing -- WMA Lossless decoder -- bluray protocol -- blackdetect filter -- libutvideo encoder wrapper (--enable-libutvideo) -- swapuv filter -- bbox filter -- XBM encoder and decoder -- RealAudio Lossless decoder -- ZeroCodec decoder -- tile video filter -- Metal Gear Solid: The Twin Snakes demuxer -- OpenEXR image decoder -- removelogo filter -- drop support for ffmpeg without libavfilter -- drawtext video filter: fontconfig support -- ffmpeg -benchmark_all option -- super2xsai filter ported from libmpcodecs -- add libavresample audio conversion library for compatibility -- MicroDVD decoder -- Avid Meridien (AVUI) encoder and decoder -- accept + prefix to -pix_fmt option to disable automatic conversions. -- complete audio filtering in libavfilter and ffmpeg -- add fps filter -- vorbis parser -- png parser -- audio mix filter -- ffv1: support (draft) version 1.3 - - -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, - CVE-2011-3945, CVE-2011-3946, CVE-2011-3947, CVE-2011-3949, - CVE-2011-3950, CVE-2011-3951, CVE-2011-3952 -- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder -- SBaGen (SBG) binaural beats script demuxer -- OpenMG Audio muxer -- Timecode extraction in DV and MOV -- thumbnail video filter -- XML output in ffprobe -- asplit audio filter -- tinterlace video filter -- astreamsync audio filter -- amerge audio filter -- ISMV (Smooth Streaming) muxer -- GSM audio parser -- SMJPEG muxer -- XWD encoder and decoder -- Automatic thread count based on detection number of (available) CPU cores -- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder -- ffprobe -show_error option -- Avid 1:1 10-bit RGB Packer codec -- v308 Quicktime Uncompressed 4:4:4 encoder and decoder -- yuv4 libquicktime packed 4:2:0 encoder and decoder -- ffprobe -show_frames option -- silencedetect audio filter -- ffprobe -show_program_version, -show_library_versions, -show_versions options -- rv34: frame-level multi-threading -- optimized iMDCT transform on x86 using SSE for for mpegaudiodec -- Improved PGS subtitle decoder -- dumpgraph option to lavfi device -- r210 and r10k encoders -- ffwavesynth decoder -- aviocat tool -- ffeval tool - - -version 0.9: - -- openal input device added -- boxblur filter added -- BWF muxer -- Flash Screen Video 2 decoder -- lavfi input device added -- added avconv, which is almost the same for now, except -for a few incompatible changes in the options, which will hopefully make them -easier to use. The changes are: - * The options placement is now strictly enforced! While in theory the - options for ffmpeg should be given in [input options] -i INPUT [output - options] OUTPUT order, in practice it was possible to give output options - before the -i and it mostly worked. Except when it didn't - the behavior was - a bit inconsistent. In avconv, it is not possible to mix input and output - options. All non-global options are reset after an input or output filename. - * All per-file options are now truly per-file - they apply only to the next - input or output file and specifying different values for different files - will now work properly (notably -ss and -t options). - * All per-stream options are now truly per-stream - it is possible to - specify which stream(s) should a given option apply to. See the Stream - specifiers section in the avconv manual for details. - * In ffmpeg some options (like -newvideo/-newaudio/...) are irregular in the - sense that they're specified after the output filename instead of before, - like all other options. In avconv this irregularity is removed, all options - apply to the next input or output file. - * -newvideo/-newaudio/-newsubtitle options were removed. Not only were they - irregular and highly confusing, they were also redundant. In avconv the -map - option will create new streams in the output file and map input streams to - them. E.g. avconv -i INPUT -map 0 OUTPUT will create an output stream for - each stream in the first input file. - * The -map option now has slightly different and more powerful syntax: - + Colons (':') are used to separate file index/stream type/stream index - instead of dots. Comma (',') is used to separate the sync stream instead - of colon.. This is done for consistency with other options. - + It's possible to specify stream type. E.g. -map 0:a:2 creates an - output stream from the third input audio stream. - + Omitting the stream index now maps all the streams of the given type, - not just the first. E.g. -map 0:s creates output streams for all the - subtitle streams in the first input file. - + Since -map can now match multiple streams, negative mappings were - introduced. Negative mappings disable some streams from an already - defined map. E.g. '-map 0 -map -0:a:1' means 'create output streams for - all the stream in the first input file, except for the second audio - stream'. - * There is a new option -c (or -codec) for choosing the decoder/encoder to - use, which allows to precisely specify target stream(s) consistently with - other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0 - libvorbis sets the codec for the first audio stream and -c copy copies all - the streams without reencoding. Old -vcodec/-acodec/-scodec options are now - aliases to -c:v/a/s - * It is now possible to precisely specify which stream should an AVOption - apply to. E.g. -b:v:0 2M sets the bitrate for the first video stream, while - -b:a 128k sets the bitrate for all audio streams. Note that the old -ab 128k - syntax is deprecated and will stop working soon. - * -map_chapters now takes only an input file index and applies to the next - output file. This is consistent with how all the other options work. - * -map_metadata now takes only an input metadata specifier and applies to - the next output file. Output metadata specifier is now part of the option - name, similarly to the AVOptions/map/codec feature above. - * -metadata can now be used to set metadata on streams and chapters, e.g. - -metadata:s:1 language=eng sets the language of the first stream to 'eng'. - This made -vlang/-alang/-slang options redundant, so they were removed. - * -qscale option now uses stream specifiers and applies to all streams, not - just video. I.e. plain -qscale number would now apply to all streams. To get - the old behavior, use -qscale:v. Also there is now a shortcut -q for -qscale - and -aq is now an alias for -q:a. - * -vbsf/-absf/-sbsf options were removed and replaced by a -bsf option which - uses stream specifiers. Use -bsf:v/a/s instead of the old options. - * -itsscale option now uses stream specifiers, so its argument is only the - scale parameter. - * -intra option was removed, use -g 0 for the same effect. - * -psnr option was removed, use -flags +psnr for the same effect. - * -vf option is now an alias to the new -filter option, which uses stream specifiers. - * -vframes/-aframes/-dframes options are now aliases to the new -frames option. - * -vtag/-atag/-stag options are now aliases to the new -tag option. -- XMV demuxer -- LOAS demuxer -- ashowinfo filter added -- Windows Media Image decoder -- amovie source added -- LATM muxer/demuxer -- Speex encoder via libspeex -- JSON output in ffprobe -- WTV muxer -- Optional C++ Support (needed for libstagefright) -- H.264 Decoding on Android via Stagefright -- Prores decoder -- BIN/XBIN/ADF/IDF text file decoder -- aconvert audio filter added -- audio support to lavfi input device added -- libcdio-paranoia input device for audio CD grabbing -- Apple ProRes decoder -- CELT in Ogg demuxing -- G.723.1 demuxer and decoder -- libmodplug support (--enable-libmodplug) -- VC-1 interlaced decoding -- libutvideo wrapper (--enable-libutvideo) -- aevalsrc audio source added -- Ut Video decoder -- Speex encoding via libspeex -- 4:2:2 H.264 decoding support -- 4:2:2 and 4:4:4 H.264 encoding with libx264 -- Pulseaudio input device -- Prores encoder -- Video Decoder Acceleration (VDA) HWAccel module. -- replacement Indeo 3 decoder -- new ffmpeg option: -map_channel -- volume audio filter added -- earwax audio filter added -- libv4l2 support (--enable-libv4l2) -- TLS/SSL and HTTPS protocol support -- AVOptions API rewritten and documented -- most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in - AVCodecContext deprecated. Codec private options should be used instead. -- Properly working defaults in libx264 wrapper, support for native presets. -- Encrypted OMA files support -- Discworld II BMV decoding support -- VBLE Decoder -- OS X Video Decoder Acceleration (VDA) support -- compact and csv output in ffprobe -- pan audio filter -- IFF Amiga Continuous Bitmap (ACBM) decoder -- ass filter -- CRI ADX audio format muxer and demuxer -- Playstation Portable PMP format demuxer -- Microsoft Windows ICO demuxer -- life source -- PCM format support in OMA demuxer -- CLJR encoder -- new option: -report -- Dxtory capture format decoder -- cellauto source -- Simple segmenting muxer -- Indeo 4 decoder -- SMJPEG demuxer -- Megalux Frame demuxer - - -version 0.8: - -- many many things we forgot because we rather write code than changelogs -- WebM support in Matroska de/muxer -- low overhead Ogg muxing -- MMS-TCP support -- VP8 de/encoding via libvpx -- Demuxer for On2's IVF format -- Pictor/PC Paint decoder -- HE-AAC v2 decoder -- HE-AAC v2 encoding with libaacplus -- libfaad2 wrapper removed -- DTS-ES extension (XCh) decoding support -- native VP8 decoder -- RTSP tunneling over HTTP -- RTP depacketization of SVQ3 -- -strict inofficial replaced by -strict unofficial -- ffplay -exitonkeydown and -exitonmousedown options added -- native GSM / GSM MS decoder -- RTP depacketization of QDM2 -- ANSI/ASCII art playback system -- Lego Mindstorms RSO de/muxer -- libavcore added (and subsequently removed) -- SubRip subtitle file muxer and demuxer -- Chinese AVS encoding via libxavs -- ffprobe -show_packets option added -- RTP packetization of Theora and Vorbis -- RTP depacketization of MP4A-LATM -- RTP packetization and depacketization of VP8 -- hflip filter -- Apple HTTP Live Streaming demuxer -- a64 codec -- MMS-HTTP support -- G.722 ADPCM audio encoder/decoder -- R10k video decoder -- ocv_smooth filter -- frei0r wrapper filter -- change crop filter syntax to width:height:x:y -- make the crop filter accept parametric expressions -- make ffprobe accept AVFormatContext options -- yadif filter -- blackframe filter -- Demuxer for Leitch/Harris' VR native stream format (LXF) -- RTP depacketization of the X-QT QuickTime format -- SAP (Session Announcement Protocol, RFC 2974) muxer and demuxer -- cropdetect filter -- ffmpeg -crop* options removed -- transpose filter added -- ffmpeg -force_key_frames option added -- demuxer for receiving raw rtp:// URLs without an SDP description -- single stream LATM/LOAS decoder -- setpts filter added -- Win64 support for optimized x86 assembly functions -- MJPEG/AVI1 to JPEG/JFIF bitstream filter -- ASS subtitle encoder and decoder -- IEC 61937 encapsulation for E-AC-3, TrueHD, DTS-HD (for HDMI passthrough) -- overlay filter added -- rename aspect filter to setdar, and pixelaspect to setsar -- IEC 61937 demuxer -- Mobotix .mxg demuxer -- frei0r source added -- hqdn3d filter added -- RTP depacketization of QCELP -- FLAC parser added -- gradfun filter added -- AMR-WB decoder -- replace the ocv_smooth filter with a more generic ocv filter -- Windows Televison (WTV) demuxer -- FFmpeg metadata format muxer and demuxer -- SubRip (srt) subtitle encoder and decoder -- floating-point AC-3 encoder added -- Lagarith decoder -- ffmpeg -copytb option added -- IVF muxer added -- Wing Commander IV movies decoder added -- movie source added -- Bink version 'b' audio and video decoder -- Bitmap Brothers JV playback system -- Apple HTTP Live Streaming protocol handler -- sndio support for playback and record -- Linux framebuffer input device added -- Chronomaster DFA decoder -- DPX image encoder -- MicroDVD subtitle file muxer and demuxer -- Playstation Portable PMP format demuxer -- fieldorder video filter added -- AAC encoding via libvo-aacenc -- AMR-WB encoding via libvo-amrwbenc -- xWMA demuxer -- Mobotix MxPEG decoder -- VP8 frame-multithreading -- NEON optimizations for VP8 -- Lots of deprecated API cruft removed -- fft and imdct optimizations for AVX (Sandy Bridge) processors -- showinfo filter added -- SMPTE 302M AES3 audio decoder -- Apple Core Audio Format muxer -- 9bit and 10bit per sample support in the H.264 decoder -- 9bit and 10bit FFV1 encoding / decoding -- split filter added -- select filter added -- sdl output device added -- libmpcodecs video filter support (3 times as many filters than before) -- mpeg2 aspect ratio dection fixed -- libxvid aspect pickiness fixed -- Frame multithreaded decoding -- E-AC-3 audio encoder -- ac3enc: add channel coupling support -- floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders. -- H264/MPEG frame-level multi-threading -- All av_metadata_* functions renamed to av_dict_* and moved to libavutil -- 4:4:4 H.264 decoding support -- 10-bit H.264 optimizations for x86 -- lut, lutrgb, and lutyuv filters added -- buffersink libavfilter sink added -- Bump libswscale for recently reported ABI break -- New J2K encoder (via OpenJPEG) - - -version 0.7: - -- all the changes for 0.8, but keeping API/ABI compatibility with the 0.6 release - - -version 0.6: - -- PB-frame decoding for H.263 -- deprecated vhook subsystem removed -- deprecated old scaler removed -- VQF demuxer -- Alpha channel scaler -- PCX encoder -- RTP packetization of H.263 -- RTP packetization of AMR -- RTP depacketization of Vorbis -- CorePNG decoding support -- Cook multichannel decoding support -- introduced avlanguage helpers in libavformat -- 8088flex TMV demuxer and decoder -- per-stream language-tags extraction in asfdec -- V210 decoder and encoder -- remaining GPL parts in AC-3 decoder converted to LGPL -- QCP demuxer -- SoX native format muxer and demuxer -- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries -- DPX image decoder -- Electronic Arts Madcow decoder -- DivX (XSUB) subtitle encoder -- nonfree libamr support for AMR-NB/WB decoding/encoding removed -- experimental AAC encoder -- RTP depacketization of ASF and RTSP from WMS servers -- RTMP support in libavformat -- noX handling for OPT_BOOL X options -- Wave64 demuxer -- IEC-61937 compatible Muxer -- TwinVQ decoder -- Bluray (PGS) subtitle decoder -- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks) -- WMA Pro decoder -- Core Audio Format demuxer -- Atrac1 decoder -- MD STUDIO audio demuxer -- RF64 support in WAV demuxer -- MPEG-4 Audio Lossless Coding (ALS) decoder -- -formats option split into -formats, -codecs, -bsfs, and -protocols -- IV8 demuxer -- CDG demuxer and decoder -- R210 decoder -- Auravision Aura 1 and 2 decoders -- Deluxe Paint Animation playback system -- SIPR decoder -- Adobe Filmstrip muxer and demuxer -- RTP depacketization of H.263 -- Bink demuxer and audio/video decoders -- enable symbol versioning by default for linkers that support it -- IFF PBM/ILBM bitmap decoder -- concat protocol -- Indeo 5 decoder -- RTP depacketization of AMR -- WMA Voice decoder -- ffprobe tool -- AMR-NB decoder -- RTSP muxer -- HE-AAC v1 decoder -- Kega Game Video (KGV1) decoder -- VorbisComment writing for FLAC, Ogg FLAC and Ogg Speex files -- RTP depacketization of Theora -- HTTP Digest authentication -- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp -- Psygnosis YOP demuxer and video decoder -- spectral extension support in the E-AC-3 decoder -- unsharp video filter -- RTP hinting in the mov/3gp/mp4 muxer -- Dirac in Ogg demuxing -- seek to keyframes in Ogg -- 4:2:2 and 4:4:4 Theora decoding -- 35% faster VP3/Theora decoding -- faster AAC decoding -- faster H.264 decoding -- RealAudio 1.0 (14.4K) encoder - - -version 0.5: - -- DV50 AKA DVCPRO50 encoder, decoder, muxer and demuxer -- TechSmith Camtasia (TSCC) video decoder -- IBM Ultimotion (ULTI) video decoder -- Sierra Online audio file demuxer and decoder -- Apple QuickDraw (qdrw) video decoder -- Creative ADPCM audio decoder (16 bits as well as 8 bits schemes) -- Electronic Arts Multimedia (WVE/UV2/etc.) file demuxer -- Miro VideoXL (VIXL) video decoder -- H.261 video encoder -- QPEG video decoder -- Nullsoft Video (NSV) file demuxer -- Shorten audio decoder -- LOCO video decoder -- Apple Lossless Audio Codec (ALAC) decoder -- Winnov WNV1 video decoder -- Autodesk Animator Studio Codec (AASC) decoder -- Indeo 2 video decoder -- Fraps FPS1 video decoder -- Snow video encoder/decoder -- Sonic audio encoder/decoder -- Vorbis audio decoder -- Macromedia ADPCM decoder -- Duck TrueMotion 2 video decoder -- support for decoding FLX and DTA extensions in FLIC files -- H.264 custom quantization matrices support -- ffserver fixed, it should now be usable again -- QDM2 audio decoder -- Real Cooker audio decoder -- TrueSpeech audio decoder -- WMA2 audio decoder fixed, now all files should play correctly -- RealAudio 14.4 and 28.8 decoders fixed -- JPEG-LS decoder -- build system improvements -- tabs and trailing whitespace removed from the codebase -- CamStudio video decoder -- AIFF/AIFF-C audio format, encoding and decoding -- ADTS AAC file reading and writing -- Creative VOC file reading and writing -- American Laser Games multimedia (*.mm) playback system -- Zip Motion Blocks Video decoder -- improved Theora/VP3 decoder -- True Audio (TTA) decoder -- AVS demuxer and video decoder -- JPEG-LS encoder -- Smacker demuxer and decoder -- NuppelVideo/MythTV demuxer and RTjpeg decoder -- KMVC decoder -- MPEG-2 intra VLC support -- MPEG-2 4:2:2 encoder -- Flash Screen Video decoder -- GXF demuxer -- Chinese AVS decoder -- GXF muxer -- MXF demuxer -- VC-1/WMV3/WMV9 video decoder -- MacIntel support -- AVISynth support -- VMware video decoder -- VP5 video decoder -- VP6 video decoder -- WavPack lossless audio decoder -- Targa (.TGA) picture decoder -- Vorbis audio encoder -- Delphine Software .cin demuxer/audio and video decoder -- Tiertex .seq demuxer/video decoder -- MTV demuxer -- TIFF picture encoder and decoder -- GIF picture decoder -- Intel Music Coder decoder -- Zip Motion Blocks Video encoder -- Musepack decoder -- Flash Screen Video encoder -- Theora encoding via libtheora -- BMP encoder -- WMA encoder -- GSM-MS encoder and decoder -- DCA decoder -- DXA demuxer and decoder -- DNxHD decoder -- Gamecube movie (.THP) playback system -- Blackfin optimizations -- Interplay C93 demuxer and video decoder -- Bethsoft VID demuxer and video decoder -- CRYO APC demuxer -- Atrac3 decoder -- V.Flash PTX decoder -- RoQ muxer, RoQ audio encoder -- Renderware TXD demuxer and decoder -- extern C declarations for C++ removed from headers -- sws_flags command line option -- codebook generator -- RoQ video encoder -- QTRLE encoder -- OS/2 support removed and restored again -- AC-3 decoder -- NUT muxer -- additional SPARC (VIS) optimizations -- Matroska muxer -- slice-based parallel H.264 decoding -- Monkey's Audio demuxer and decoder -- AMV audio and video decoder -- DNxHD encoder -- H.264 PAFF decoding -- Nellymoser ASAO decoder -- Beam Software SIFF demuxer and decoder -- libvorbis Vorbis decoding removed in favor of native decoder -- IntraX8 (J-Frame) subdecoder for WMV2 and VC-1 -- Ogg (Theora, Vorbis and FLAC) muxer -- The "device" muxers and demuxers are now in a new libavdevice library -- PC Paintbrush PCX decoder -- Sun Rasterfile decoder -- TechnoTrend PVA demuxer -- Linux Media Labs MPEG-4 (LMLM4) demuxer -- AVM2 (Flash 9) SWF muxer -- QT variant of IMA ADPCM encoder -- VFW grabber -- iPod/iPhone compatible mp4 muxer -- Mimic decoder -- MSN TCP Webcam stream demuxer -- RL2 demuxer / decoder -- IFF demuxer -- 8SVX audio decoder -- non-recursive Makefiles -- BFI demuxer -- MAXIS EA XA (.xa) demuxer / decoder -- BFI video decoder -- OMA demuxer -- MLP/TrueHD decoder -- Electronic Arts CMV decoder -- Motion Pixels Video decoder -- Motion Pixels MVI demuxer -- removed animated GIF decoder/demuxer -- D-Cinema audio muxer -- Electronic Arts TGV decoder -- Apple Lossless Audio Codec (ALAC) encoder -- AAC decoder -- floating point PCM encoder/decoder -- MXF muxer -- DV100 AKA DVCPRO HD decoder and demuxer -- E-AC-3 support added to AC-3 decoder -- Nellymoser ASAO encoder -- ASS and SSA demuxer and muxer -- liba52 wrapper removed -- SVQ3 watermark decoding support -- Speex decoding via libspeex -- Electronic Arts TGQ decoder -- RV40 decoder -- QCELP / PureVoice decoder -- RV30 decoder -- hybrid WavPack support -- R3D REDCODE demuxer -- ALSA support for playback and record -- Electronic Arts TQI decoder -- OpenJPEG based JPEG 2000 decoder -- NC (NC4600) camera file demuxer -- Gopher client support -- MXF D-10 muxer -- generic metadata API -- flash ScreenVideo2 encoder - - -version 0.4.9-pre1: - -- DV encoder, DV muxer -- Microsoft RLE video decoder -- Microsoft Video-1 decoder -- Apple Animation (RLE) decoder -- Apple Graphics (SMC) decoder -- Apple Video (RPZA) decoder -- Cinepak decoder -- Sega FILM (CPK) file demuxer -- Westwood multimedia support (VQA & AUD files) -- Id Quake II CIN playback support -- 8BPS video decoder -- FLIC playback support -- RealVideo 2.0 (RV20) decoder -- Duck TrueMotion v1 (DUCK) video decoder -- Sierra VMD demuxer and video decoder -- MSZH and ZLIB decoder support -- SVQ1 video encoder -- AMR-WB support -- PPC optimizations -- rate distortion optimal cbp support -- rate distorted optimal ac prediction for MPEG-4 -- rate distorted optimal lambda->qp support -- AAC encoding with libfaac -- Sunplus JPEG codec (SP5X) support -- use Lagrange multipler instead of QP for ratecontrol -- Theora/VP3 decoding support -- XA and ADX ADPCM codecs -- export MPEG-2 active display area / pan scan -- Add support for configuring with IBM XLC -- floating point AAN DCT -- initial support for zygo video (not complete) -- RGB ffv1 support -- new audio/video parser API -- av_log() system -- av_read_frame() and av_seek_frame() support -- missing last frame fixes -- seek by mouse in ffplay -- noise reduction of DCT coefficients -- H.263 OBMC & 4MV support -- H.263 alternative inter vlc support -- H.263 loop filter -- H.263 slice structured mode -- interlaced DCT support for MPEG-2 encoding -- stuffing to stay above min_bitrate -- MB type & QP visualization -- frame stepping for ffplay -- interlaced motion estimation -- alternate scantable support -- SVCD scan offset support -- closed GOP support -- SSE2 FDCT -- quantizer noise shaping -- G.726 ADPCM audio codec -- MS ADPCM encoding -- multithreaded/SMP motion estimation -- multithreaded/SMP encoding for MPEG-1/MPEG-2/MPEG-4/H.263 -- multithreaded/SMP decoding for MPEG-2 -- FLAC decoder -- Metrowerks CodeWarrior suppport -- H.263+ custom pcf support -- nicer output for 'ffmpeg -formats' -- Matroska demuxer -- SGI image format, encoding and decoding -- H.264 loop filter support -- H.264 CABAC support -- nicer looking arrows for the motion vector visualization -- improved VCD support -- audio timestamp drift compensation -- MPEG-2 YUV 422/444 support -- polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample -- better image scaling -- H.261 support -- correctly interleave packets during encoding -- VIS optimized motion compensation -- intra_dc_precision>0 encoding support -- support reuse of motion vectors/MB types/field select values of the source video -- more accurate deblock filter -- padding support -- many optimizations and bugfixes -- FunCom ISS audio file demuxer and according ADPCM decoding - - -version 0.4.8: - -- MPEG-2 video encoding (Michael) -- Id RoQ playback subsystem (Mike Melanson and Tim Ferguson) -- Wing Commander III Movie (.mve) file playback subsystem (Mike Melanson - and Mario Brito) -- Xan DPCM audio decoder (Mario Brito) -- Interplay MVE playback subsystem (Mike Melanson) -- Duck DK3 and DK4 ADPCM audio decoders (Mike Melanson) - - -version 0.4.7: - -- RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, code from mplayerhq - (originally from public domain player for Amiga at http://www.honeypot.net/audio) -- current version now also compiles with older GCC (Fabrice) -- 4X multimedia playback system including 4xm file demuxer (Mike - Melanson), and 4X video and audio codecs (Michael) -- Creative YUV (CYUV) decoder (Mike Melanson) -- FFV1 codec (our very simple lossless intra only codec, compresses much better - than HuffYUV) (Michael) -- ASV1 (Asus), H.264, Intel indeo3 codecs have been added (various) -- tiny PNG encoder and decoder, tiny GIF decoder, PAM decoder (PPM with - alpha support), JPEG YUV colorspace support. (Fabrice Bellard) -- ffplay has been replaced with a newer version which uses SDL (optionally) - for multiplatform support (Fabrice) -- Sorenson Version 3 codec (SVQ3) support has been added (decoding only) - donated - by anonymous -- AMR format has been added (Johannes Carlsson) -- 3GP support has been added (Johannes Carlsson) -- VP3 codec has been added (Mike Melanson) -- more MPEG-1/2 fixes -- better multiplatform support, MS Visual Studio fixes (various) -- AltiVec optimizations (Magnus Damn and others) -- SH4 processor support has been added (BERO) -- new public interfaces (avcodec_get_pix_fmt) (Roman Shaposhnick) -- VOB streaming support (Brian Foley) -- better MP3 autodetection (Andriy Rysin) -- qpel encoding (Michael) -- 4mv+b frames encoding finally fixed (Michael) -- chroma ME (Michael) -- 5 comparison functions for ME (Michael) -- B-frame encoding speedup (Michael) -- WMV2 codec (unfinished - Michael) -- user specified diamond size for EPZS (Michael) -- Playstation STR playback subsystem, still experimental (Mike and Michael) -- ASV2 codec (Michael) -- CLJR decoder (Alex) - -.. And lots more new enhancements and fixes. - - -version 0.4.6: - -- completely new integer only MPEG audio layer 1/2/3 decoder rewritten - from scratch -- Recoded DCT and motion vector search with gcc (no longer depends on nasm) -- fix quantization bug in AC3 encoder -- added PCM codecs and format. Corrected WAV/AVI/ASF PCM issues -- added prototype ffplay program -- added GOB header parsing on H.263/H.263+ decoder (Juanjo) -- bug fix on MCBPC tables of H.263 (Juanjo) -- bug fix on DC coefficients of H.263 (Juanjo) -- added Advanced Prediction Mode on H.263/H.263+ decoder (Juanjo) -- now we can decode H.263 streams found in QuickTime files (Juanjo) -- now we can decode H.263 streams found in VIVO v1 files(Juanjo) -- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo) -- added GOB header for H.263/H.263+ coding on RTP mode (Juanjo) -- now H.263 picture size is returned on the first decoded frame (Juanjo) -- added first regression tests -- added MPEG-2 TS demuxer -- new demux API for libav -- more accurate and faster IDCT (Michael) -- faster and entropy-controlled motion search (Michael) -- two pass video encoding (Michael) -- new video rate control (Michael) -- added MSMPEG4V1, MSMPEGV2 and WMV1 support (Michael) -- great performance improvement of video encoders and decoders (Michael) -- new and faster bit readers and vlc parsers (Michael) -- high quality encoding mode: tries all macroblock/VLC types (Michael) -- added DV video decoder -- preliminary RTP/RTSP support in ffserver and libavformat -- H.263+ AIC decoding/encoding support (Juanjo) -- VCD MPEG-PS mode (Juanjo) -- PSNR stuff (Juanjo) -- simple stats output (Juanjo) -- 16-bit and 15-bit RGB/BGR/GBR support (Bisqwit) - - -version 0.4.5: - -- some header fixes (Zdenek Kabelac ) -- many MMX optimizations (Nick Kurshev ) -- added configure system (actually a small shell script) -- added MPEG audio layer 1/2/3 decoding using LGPL'ed mpglib by - Michael Hipp (temporary solution - waiting for integer only - decoder) -- fixed VIDIOCSYNC interrupt -- added Intel H.263 decoding support ('I263' AVI fourCC) -- added Real Video 1.0 decoding (needs further testing) -- simplified image formats again. Added PGM format (=grey - pgm). Renamed old PGM to PGMYUV. -- fixed msmpeg4 slice issues (tell me if you still find problems) -- fixed OpenDivX bugs with newer versions (added VOL header decoding) -- added support for MPlayer interface -- added macroblock skip optimization -- added MJPEG decoder -- added mmx/mmxext IDCT from libmpeg2 -- added pgmyuvpipe, ppm, and ppm_pipe formats (original patch by Celer - ) -- added pixel format conversion layer (e.g. for MJPEG or PPM) -- added deinterlacing option -- MPEG-1/2 fixes -- MPEG-4 vol header fixes (Jonathan Marsden ) -- ARM optimizations (Lionel Ulmer ). -- Windows porting of file converter -- added MJPEG raw format (input/output) -- added JPEG image format support (input/output) - - -version 0.4.4: - -- fixed some std header definitions (Bjorn Lindgren - ). -- added MPEG demuxer (MPEG-1 and 2 compatible). -- added ASF demuxer -- added prototype RM demuxer -- added AC3 decoding (done with libac3 by Aaron Holtzman) -- added decoding codec parameter guessing (.e.g. for MPEG, because the - header does not include them) -- fixed header generation in MPEG-1, AVI and ASF muxer: wmplayer can now - play them (only tested video) -- fixed H.263 white bug -- fixed phase rounding in img resample filter -- add MMX code for polyphase img resample filter -- added CPU autodetection -- added generic title/author/copyright/comment string handling (ASF and RM - use them) -- added SWF demux to extract MP3 track (not usable yet because no MP3 - decoder) -- added fractional frame rate support -- codecs are no longer searched by read_header() (should fix ffserver - segfault) - - -version 0.4.3: - -- BGR24 patch (initial patch by Jeroen Vreeken ) -- fixed raw yuv output -- added motion rounding support in MPEG-4 -- fixed motion bug rounding in MSMPEG4 -- added B-frame handling in video core -- added full MPEG-1 decoding support -- added partial (frame only) MPEG-2 support -- changed the FOURCC code for H.263 to "U263" to be able to see the - +AVI/H.263 file with the UB Video H.263+ decoder. MPlayer works with - this +codec ;) (JuanJo). -- Halfpel motion estimation after MB type selection (JuanJo) -- added pgm and .Y.U.V output format -- suppressed 'img:' protocol. Simply use: /tmp/test%d.[pgm|Y] as input or - output. -- added pgmpipe I/O format (original patch from Martin Aumueller - , but changed completely since we use a format - instead of a protocol) - - -version 0.4.2: - -- added H.263/MPEG-4/MSMPEG4 decoding support. MPEG-4 decoding support - (for OpenDivX) is almost complete: 8x8 MVs and rounding are - missing. MSMPEG4 support is complete. -- added prototype MPEG-1 decoder. Only I- and P-frames handled yet (it - can decode ffmpeg MPEGs :-)). -- added libavcodec API documentation (see apiexample.c). -- fixed image polyphase bug (the bottom of some images could be - greenish) -- added support for non clipped motion vectors (decoding only) - and image sizes non-multiple of 16 -- added support for AC prediction (decoding only) -- added file overwrite confirmation (can be disabled with -y) -- added custom size picture to H.263 using H.263+ (Juanjo) - - -version 0.4.1: - -- added MSMPEG4 (aka DivX) compatible encoder. Changed default codec - of AVI and ASF to DIV3. -- added -me option to set motion estimation method - (default=log). suppressed redundant -hq option. -- added options -acodec and -vcodec to force a given codec (useful for - AVI for example) -- fixed -an option -- improved dct_quantize speed -- factorized some motion estimation code - - -version 0.4.0: - -- removing grab code from ffserver and moved it to ffmpeg. Added - multistream support to ffmpeg. -- added timeshifting support for live feeds (option ?date=xxx in the - URL) -- added high quality image resize code with polyphase filter (need - mmx/see optimization). Enable multiple image size support in ffserver. -- added multi live feed support in ffserver -- suppressed master feature from ffserver (it should be done with an - external program which opens the .ffm url and writes it to another - ffserver) -- added preliminary support for video stream parsing (WAV and AVI half - done). Added proper support for audio/video file conversion in - ffmpeg. -- added preliminary support for video file sending from ffserver -- redesigning I/O subsystem: now using URL based input and output - (see avio.h) -- added WAV format support -- added "tty user interface" to ffmpeg to stop grabbing gracefully -- added MMX/SSE optimizations to SAD (Sums of Absolutes Differences) - (Juan J. Sierralta P. a.k.a. "Juanjo" ) -- added MMX DCT from mpeg2_movie 1.5 (Juanjo) -- added new motion estimation algorithms, log and phods (Juanjo) -- changed directories: libav for format handling, libavcodec for - codecs - - -version 0.3.4: - -- added stereo in MPEG audio encoder - - -version 0.3.3: - -- added 'high quality' mode which use motion vectors. It can be used in - real time at low resolution. -- fixed rounding problems which caused quality problems at high - bitrates and large GOP size - - -version 0.3.2: small fixes - -- ASF fixes -- put_seek bug fix - - -version 0.3.1: added avi/divx support - -- added AVI support -- added MPEG-4 codec compatible with OpenDivX. It is based on the H.263 codec -- added sound for flash format (not tested) - - -version 0.3: initial public release diff --git a/MAINTAINERS b/MAINTAINERS index 3319359bdf..6fe014a6a2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14,7 +14,6 @@ and related discussions. Project Leader ============== -Michael Niedermayer final design decisions @@ -445,10 +444,11 @@ x86 Michael Niedermayer Releases ======== +1.2 Michael Niedermayer 1.1 Michael Niedermayer 1.0 Michael Niedermayer -0.11 Michael Niedermayer +If you want to maintain an older release, please contact us GnuPG Fingerprints of maintainers and contributors diff --git a/RELEASE b/RELEASE index 3d529fb483..63b283b23a 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -1.1.git +1.1.16 diff --git a/cmdutils.c b/cmdutils.c index 38c8159e73..c67f7e3c8a 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -65,7 +65,7 @@ struct SwsContext *sws_opts; SwrContext *swr_opts; AVDictionary *format_opts, *codec_opts; -const int this_year = 2013; +const int this_year = 2015; static FILE *report_file; @@ -1851,7 +1851,7 @@ static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbu /* XXX this shouldn't be needed, but some tests break without this line * those decoders are buggy and need to be fixed. * the following tests fail: - * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit + * cdgraphics, ansi */ memset(buf->base[0], 128, ret); diff --git a/cmdutils.h b/cmdutils.h index f193132f09..12407501e6 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -190,13 +190,13 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags, void show_help_children(const AVClass *class, int flags); /** - * Per-avtool specific help handler. Implemented in each - * avtool, called by show_help(). + * Per-fftool specific help handler. Implemented in each + * fftool, called by show_help(). */ void show_help_default(const char *opt, const char *arg); /** - * Generic -h handler common to all avtools. + * Generic -h handler common to all fftools. */ int show_help(void *optctx, const char *opt, const char *arg); diff --git a/configure b/configure index 89e076fbb0..40b141b788 100755 --- a/configure +++ b/configure @@ -789,14 +789,21 @@ check_ld(){ log check_ld "$@" type=$1 shift 1 - flags=$(filter_out '-l*' $@) - libs=$(filter '-l*' $@) + flags=$(filter_out '-l*|*.so' $@) + libs=$(filter '-l*|*.so' $@) check_$type $($cflags_filter $flags) || return flags=$($ldflags_filter $flags) libs=$($ldflags_filter $libs) check_cmd $ld $LDFLAGS $flags $(ld_o $TMPE) $TMPO $libs $extralibs } +print_include(){ + hdr=$1 + test "${hdr%.h}" = "${hdr}" && + echo "#include $hdr" || + echo "#include <$hdr>" +} + check_code(){ log check_code "$@" check=$1 @@ -805,7 +812,7 @@ check_code(){ shift 3 { for hdr in $headers; do - echo "#include <$hdr>" + print_include $hdr done echo "int main(void) { $code; return 0; }" } | check_$check "$@" @@ -889,7 +896,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; }" @@ -1053,6 +1060,26 @@ require_pkg_config(){ add_extralibs $(get_safe ${pkg}_libs) } +require_libfreetype(){ + log require_libfreetype "$@" + pkg="freetype2" + check_cmd $pkg_config --exists --print-errors $pkg \ + || die "ERROR: $pkg not found" + pkg_cflags=$($pkg_config --cflags $pkg) + pkg_libs=$($pkg_config --libs $pkg) + { + echo "#include " + echo "#include FT_FREETYPE_H" + echo "long check_func(void) { return (long) FT_Init_FreeType; }" + echo "int main(void) { return 0; }" + } | check_ld "cc" $pkg_cflags $pkg_libs \ + && set_safe ${pkg}_cflags $pkg_cflags \ + && set_safe ${pkg}_libs $pkg_libs \ + || die "ERROR: $pkg not found" + add_cflags $(get_safe ${pkg}_cflags) + add_extralibs $(get_safe ${pkg}_libs) +} + hostcc_o(){ eval printf '%s\\n' $HOSTCC_O } @@ -1338,11 +1365,14 @@ HAVE_LIST=" alsa_asoundlib_h altivec_h arpa_inet_h + as_object_arch asm_mod_q asm_mod_y asm_types_h attribute_may_alias attribute_packed + cdio_paranoia_h + cdio_paranoia_paranoia_h clock_gettime closesocket cmov @@ -1464,6 +1494,7 @@ HAVE_LIST=" CONFIG_EXTRA=" aandcttables ac3dsp + audio_frame_queue error_resilience gcrypt golomb @@ -1631,7 +1662,7 @@ mpegvideoenc_select="mpegvideo" # decoders / encoders aac_decoder_select="mdct sinewin" -aac_encoder_select="mdct sinewin" +aac_encoder_select="audio_frame_queue mdct sinewin" aac_latm_decoder_select="aac_decoder aac_latm_parser" ac3_decoder_select="mdct ac3dsp ac3_parser" ac3_encoder_select="mdct ac3dsp" @@ -1716,13 +1747,13 @@ msmpeg4v3_decoder_select="h263_decoder" msmpeg4v3_encoder_select="h263_encoder" mss2_decoder_select="vc1_decoder" nellymoser_decoder_select="mdct sinewin" -nellymoser_encoder_select="mdct sinewin" +nellymoser_encoder_select="audio_frame_queue mdct sinewin" nuv_decoder_select="lzo" png_decoder_select="zlib" png_encoder_select="zlib" qcelp_decoder_select="lsp" qdm2_decoder_select="mdct rdft mpegaudiodsp" -ra_144_encoder_select="lpc" +ra_144_encoder_select="audio_frame_queue lpc" ralf_decoder_select="golomb" rv10_decoder_select="h263_decoder" rv10_encoder_select="h263_encoder" @@ -1732,7 +1763,7 @@ rv30_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvi rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo" shorten_decoder_select="golomb" sipr_decoder_select="lsp" -snow_decoder_select="dwt rangecoder" +snow_decoder_select="dwt rangecoder videodsp" snow_encoder_select="aandcttables dwt error_resilience mpegvideoenc rangecoder" sonic_decoder_select="golomb" sonic_encoder_select="golomb" @@ -1778,14 +1809,15 @@ zmbv_encoder_select="zlib" # hardware accelerators crystalhd_deps="libcrystalhd_libcrystalhd_if_h" +dxva2_deps="dxva2api_h" vaapi_deps="va_va_h" vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" h263_vaapi_hwaccel_select="vaapi h263_decoder" h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser" -h264_dxva2_hwaccel_deps="dxva2api_h" -h264_dxva2_hwaccel_select="dxva2 h264_decoder" +h264_dxva2_hwaccel_deps="dxva2" +h264_dxva2_hwaccel_select="h264_decoder" h264_vaapi_hwaccel_select="vaapi h264_decoder" h264_vda_decoder_select="vda h264_parser h264_decoder" h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" @@ -1795,8 +1827,8 @@ mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder" mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder" mpeg1_vdpau_hwaccel_select="vdpau mpeg1video_decoder" mpeg2_crystalhd_decoder_select="crystalhd" -mpeg2_dxva2_hwaccel_deps="dxva2api_h" -mpeg2_dxva2_hwaccel_select="dxva2 mpeg2video_decoder" +mpeg2_dxva2_hwaccel_deps="dxva2" +mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" mpeg2_vdpau_hwaccel_select="vdpau mpeg2video_decoder" mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder" mpeg4_crystalhd_decoder_select="crystalhd" @@ -1804,8 +1836,8 @@ mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder" mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder" msmpeg4_crystalhd_decoder_select="crystalhd" vc1_crystalhd_decoder_select="crystalhd" -vc1_dxva2_hwaccel_deps="dxva2api_h" -vc1_dxva2_hwaccel_select="dxva2 vc1_decoder" +vc1_dxva2_hwaccel_deps="dxva2" +vc1_dxva2_hwaccel_select="vc1_decoder" vc1_vaapi_hwaccel_select="vaapi vc1_decoder" vc1_vdpau_decoder_select="vdpau vc1_decoder" wmv3_crystalhd_decoder_select="crystalhd" @@ -1823,7 +1855,9 @@ vc1_parser_select="error_resilience mpegvideo" libaacplus_encoder_deps="libaacplus" libcelt_decoder_deps="libcelt" libfaac_encoder_deps="libfaac" +libfaac_encoder_select="audio_frame_queue" libfdk_aac_encoder_deps="libfdk_aac" +libfdk_aac_encoder_select="audio_frame_queue" libgsm_decoder_deps="libgsm" libgsm_encoder_deps="libgsm" libgsm_ms_decoder_deps="libgsm" @@ -1832,24 +1866,30 @@ libilbc_decoder_deps="libilbc" libilbc_encoder_deps="libilbc" libmodplug_demuxer_deps="libmodplug" libmp3lame_encoder_deps="libmp3lame" +libmp3lame_encoder_select="audio_frame_queue" libopencore_amrnb_decoder_deps="libopencore_amrnb" libopencore_amrnb_encoder_deps="libopencore_amrnb" +libopencore_amrnb_encoder_select="audio_frame_queue" libopencore_amrwb_decoder_deps="libopencore_amrwb" libopenjpeg_decoder_deps="libopenjpeg" libopenjpeg_encoder_deps="libopenjpeg" libopus_decoder_deps="libopus" libopus_encoder_deps="libopus" +libopus_encoder_select="audio_frame_queue" libschroedinger_decoder_deps="libschroedinger" libschroedinger_encoder_deps="libschroedinger" libspeex_decoder_deps="libspeex" libspeex_encoder_deps="libspeex" +libspeex_encoder_select="audio_frame_queue" libstagefright_h264_decoder_deps="libstagefright_h264" libtheora_encoder_deps="libtheora" libtwolame_encoder_deps="libtwolame" libvo_aacenc_encoder_deps="libvo_aacenc" +libvo_aacenc_encoder_select="audio_frame_queue" libvo_amrwbenc_encoder_deps="libvo_amrwbenc" libvorbis_decoder_deps="libvorbis" libvorbis_encoder_deps="libvorbis" +libvorbis_encoder_select="audio_frame_queue" libvpx_decoder_deps="libvpx" libvpx_encoder_deps="libvpx" libx264_encoder_deps="libx264" @@ -2088,6 +2128,9 @@ enable safe_bitstream_reader enable static enable swscale_alpha +# By default, enable only those hwaccels that have no external dependencies. +enable dxva2 vdpau + # build settings SHFLAGS='-shared -Wl,-soname,$$(@F)' FFSERVERLDFLAGS=-Wl,-E @@ -2545,7 +2588,9 @@ probe_cc(){ unset _depflags _DEPCMD _DEPFLAGS _flags_filter=echo - if $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then + if $_cc --version 2>&1 | grep -q '^GNU assembler'; then + true # no-op to avoid reading stdin in following checks + elif $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then _type=llvm_gcc gcc_extra_ver=$(expr "$($_cc --version | head -n1)" : '.*\((.*)\)') _ident="llvm-gcc $($_cc -dumpversion) $gcc_extra_ver" @@ -3076,7 +3121,7 @@ check_64bit(){ } case "$arch" in - alpha|ia64) + aarch64|alpha|ia64) spic=$shared ;; mips) @@ -3091,6 +3136,10 @@ case "$arch" in check_64bit ppc ppc64 'sizeof(void *) > 4' spic=$shared ;; + s390) + check_64bit s390 s390x 'sizeof(void *) > 4' + spic=$shared + ;; sparc) check_64bit sparc sparc64 'sizeof(void *) > 4' spic=$shared @@ -3516,6 +3565,11 @@ EOF enabled_all armv6t2 shared !pic && enable_pic + # llvm's integrated assembler supports .object_arch from llvm 3.5 + [ "$objformat" = elf ] && check_as <= 2.0.0" aacplus.h aacplusEncOpen -laacplus enabled libass && require_pkg_config libass ass/ass.h ass_library_init -enabled libbluray && require libbluray libbluray/bluray.h bd_open -lbluray -enabled libcdio && require2 libcdio "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio +enabled libbluray && require_pkg_config libbluray libbluray/bluray.h bd_open enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 || die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } @@ -3826,7 +3880,7 @@ enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaa enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite" enabled libflite && require2 libflite "flite/flite.h" flite_init $flite_libs -enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType +enabled libfreetype && require_libfreetype enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc enabled libmodplug && require libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug @@ -3916,7 +3970,7 @@ rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || d 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_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete check_header sys/videoio.h @@ -3954,6 +4008,9 @@ enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack && check_fu enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio +if enabled libcdio; then + check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || check_lib2 "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio +fi enabled x11grab && require X11 X11/Xlib.h XOpenDisplay -lX11 && @@ -4090,6 +4147,7 @@ elif enabled gcc; then check_optflags -fno-tree-vectorize check_cflags -Werror=implicit-function-declaration check_cflags -Werror=missing-prototypes + check_cflags -Werror=return-type check_cflags -Werror=vla elif enabled llvm_gcc; then check_cflags -mllvm -stack-alignment=16 @@ -4098,6 +4156,7 @@ elif enabled clang; then check_cflags -Qunused-arguments check_cflags -Werror=implicit-function-declaration check_cflags -Werror=missing-prototypes + check_cflags -Werror=return-type 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 a79dd2df58..8daaea3260 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -132,30 +132,30 @@ API changes, most recent first: 2012-03-26 - a67d9cf - lavfi 2.66.100 Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions. -2012-xx-xx - xxxxxxx - lavu 52.2.1 - avstring.h +2012-12-29 - 2ce43b3 / d8fd06c - lavu 52.13.100 / 52.3.0 - avstring.h Add av_basename() and av_dirname(). -2012-11-10 - 5980f5dd - lavu 52.2.0 - audioconvert.h +2012-11-11 - 03b0787 / 5980f5d - lavu 52.6.100 / 52.2.0 - audioconvert.h Rename audioconvert.h to channel_layout.h. audioconvert.h is now deprecated. -2012-10-26 - dfde8a34 - lavu 52.1.0 - intmath.h - Add av_ctz() for trailing zero bit count. +2012-11-05 - 7d26be6 / dfde8a3 - lavu 52.5.100 / 52.1.0 - intmath.h + Add av_ctz() for trailing zero bit count -2012-10-18 - a893655b - lavu 51.45.0 - error.h - Add AVERROR_EXPERIMENTAL. +2012-10-21 - e3a91c5 / a893655 - lavu 51.77.100 / 51.45.0 - error.h + Add AVERROR_EXPERIMENTAL -2012-10-12 - d2fcb356 - lavu 51.44.0 - pixdesc.h +2012-10-12 - a33ed6b / d2fcb35 - lavu 51.76.100 / 51.44.0 - pixdesc.h Add functions for accessing pixel format descriptors. Accessing the av_pix_fmt_descriptors array directly is now deprecated. -2012-10-11 - 9a92aea2 - lavu 51.43.0 - aes.h, md5.h, sha.h, tree.h +2012-10-11 - f391e40 / 9a92aea - lavu 51.75.100 / 51.43.0 - aes.h, md5.h, sha.h, tree.h Add functions for allocating the opaque contexts for the algorithms, -2012-10-10 - b522000e - lavf 54.18.0 - avio.h +2012-10-10 - de31814 / b522000 - lavf 54.32.100 / 54.18.0 - avio.h Add avio_closep to complement avio_close. -2012-10-06 - 78071a14 - lavu 51.42.0 - pixfmt.h +2012-10-08 - ae77266 / 78071a1 - lavu 51.74.100 / 51.42.0 - pixfmt.h Rename PixelFormat to AVPixelFormat and all PIX_FMT_* to AV_PIX_FMT_*. To provide backwards compatibility, PixelFormat is now #defined as AVPixelFormat. @@ -163,23 +163,23 @@ API changes, most recent first: 'PixelFormat' identifier. Such code should either #undef PixelFormat or stop using the PixelFormat name. -2012-10-05 - e7ba5b1 - lavr 1.0.0 - avresample.h +2012-10-05 - 55c49af / e7ba5b1 - lavr 1.0.0 - avresample.h Data planes parameters to avresample_convert() and avresample_read() are now uint8_t** instead of void**. Libavresample is now stable. -2012-09-24 - a42aada - lavc 54.28.0 - avcodec.h +2012-09-24 - 46a3595 / a42aada - lavc 54.59.100 / 54.28.0 - avcodec.h Add avcodec_free_frame(). This function must now be used for freeing an AVFrame. -2012-09-12 - 8919fee - lavu 51.41.0 - audioconvert.h +2012-09-12 - e3e09f2 / 8919fee - lavu 51.73.100 / 51.41.0 - audioconvert.h Added AV_CH_LOW_FREQUENCY_2 channel mask value. -2012-09-04 - 686a329 - lavu 51.40.0 - opt.h +2012-09-04 - b21b5b0 / 686a329 - lavu 51.71.100 / 51.40.0 - opt.h Reordered the fields in default_val in AVOption, changed which default_val field is used for which AVOptionType. -2012-08-30 - a231832 - lavc 54.26.1 - avcodec.h +2012-08-30 - 98298eb / a231832 - lavc 54.54.101 / 54.26.1 - avcodec.h Add codec descriptor properties AV_CODEC_PROP_LOSSY and AV_CODEC_PROP_LOSSLESS. @@ -187,90 +187,90 @@ API changes, most recent first: Add codec descriptors for accessing codec properties without having to refer to a specific decoder or encoder. - c223d79 - Add an AVCodecDescriptor struct and functions + f5f3684 / c223d79 - Add an AVCodecDescriptor struct and functions avcodec_descriptor_get() and avcodec_descriptor_next(). - 51efed1 - Add AVCodecDescriptor.props and AV_CODEC_PROP_INTRA_ONLY. - 91e59fe - Add avcodec_descriptor_get_by_name(). + f5f3684 / 51efed1 - Add AVCodecDescriptor.props and AV_CODEC_PROP_INTRA_ONLY. + 6c180b3 / 91e59fe - Add avcodec_descriptor_get_by_name(). -2012-08-08 - 987170c - lavu 51.38 - dict.h +2012-08-08 - f5f3684 / 987170c - lavu 51.68.100 / 51.38.0 - dict.h Add av_dict_count(). -2012-08-07 - 104e10f - lavc 54.25 - avcodec.h +2012-08-07 - 7a72695 / 104e10f - lavc 54.51.100 / 54.25.0 - avcodec.h Rename CodecID to AVCodecID and all CODEC_ID_* to AV_CODEC_ID_*. To provide backwards compatibility, CodecID is now #defined as AVCodecID. Note that this can break user code that includes avcodec.h and uses the 'CodecID' identifier. Such code should either #undef CodecID or stop using the CodecID name. -2012-08-03 - 239fdf1 - lavu 51.37.1 - cpu.h +2012-08-03 - e776ee8 / 239fdf1 - lavu 51.66.101 / 51.37.1 - cpu.h lsws 2.1.1 - swscale.h Rename AV_CPU_FLAG_MMX2 ---> AV_CPU_FLAG_MMXEXT. Rename SWS_CPU_CAPS_MMX2 ---> SWS_CPU_CAPS_MMXEXT. -2012-07-29 - 681ed00 - lavf 54.13.0 - avformat.h +2012-07-29 - 7c26761 / 681ed00 - lavf 54.22.100 / 54.13.0 - avformat.h Add AVFMT_FLAG_NOBUFFER for low latency use cases. 2012-07-10 - 5fade8a - lavu 51.37.0 Add av_malloc_array() and av_mallocz_array() -2012-06-22 - d3d3a32 - lavu 51.34.0 +2012-06-22 - e847f41 / d3d3a32 - lavu 51.61.100 / 51.34.0 Add av_usleep() -2012-06-20 - ae0a301 - lavu 51.33.0 +2012-06-20 - 4da42eb / ae0a301 - lavu 51.60.100 / 51.33.0 Move av_gettime() to libavutil, add libavutil/time.h -2012-06-09 - 3971be0 - lavr 0.0.3 +2012-06-09 - 82edf67 / 3971be0 - lavr 0.0.3 Add a parameter to avresample_build_matrix() for Dolby/DPLII downmixing. -2012-06-12 - 9baeff9 - lavfi 2.23.0 - avfilter.h +2012-06-12 - c7b9eab / 9baeff9 - lavfi 2.79.100 / 2.23.0 - avfilter.h Add AVFilterContext.nb_inputs/outputs. Deprecate AVFilterContext.input/output_count. -2012-06-12 - 84b9fbe - lavfi 2.22.0 - avfilter.h +2012-06-12 - c7b9eab / 84b9fbe - lavfi 2.79.100 / 2.22.0 - avfilter.h Add avfilter_pad_get_type() and avfilter_pad_get_name(). Those should now be used instead of accessing AVFilterPad members directly. -2012-06-12 - b0f0dfc - lavu 51.32.0 - audioconvert.h +2012-06-12 - 3630a07 / b0f0dfc - lavu 51.57.100 / 51.32.0 - audioconvert.h Add av_get_channel_layout_channel_index(), av_get_channel_name() and av_channel_layout_extract_channel(). -2012-05-25 - 154486f - lavu 51.31.0 - opt.h +2012-05-25 - 53ce990 / 154486f - lavu 51.55.100 / 51.31.0 - opt.h Add av_opt_set_bin() -2012-05-15 - lavfi 2.17.0 +2012-05-15 - lavfi 2.74.100 / 2.17.0 Add support for audio filters - ac71230/a2cd9be - add video/audio buffer sink in a new installed + 61930bd / ac71230, 1cbf7fb / a2cd9be - add video/audio buffer sink in a new installed header buffersink.h - 720c6b7 - add av_buffersrc_write_frame(), deprecate + 1cbf7fb / 720c6b7 - add av_buffersrc_write_frame(), deprecate av_vsrc_buffer_add_frame() - ab16504 - add avfilter_copy_buf_props() - 9453c9e - add extended_data to AVFilterBuffer - 1b8c927 - add avfilter_get_audio_buffer_ref_from_arrays() + 61930bd / ab16504 - add avfilter_copy_buf_props() + 61930bd / 9453c9e - add extended_data to AVFilterBuffer + 61930bd / 1b8c927 - add avfilter_get_audio_buffer_ref_from_arrays() -2012-05-09 - lavu 51.30.0 - samplefmt.h - 142e740 - add av_samples_copy() - 6d7f617 - add av_samples_set_silence() +2012-05-09 - lavu 51.53.100 / 51.30.0 - samplefmt.h + 61930bd / 142e740 - add av_samples_copy() + 61930bd / 6d7f617 - add av_samples_set_silence() -2012-05-09 - a5117a2 - lavc 54.13.1 +2012-05-09 - 61930bd / a5117a2 - lavc 54.21.101 / 54.13.1 For audio formats with fixed frame size, the last frame no longer needs to be padded with silence, libavcodec will handle this internally (effectively all encoders behave as if they had CODEC_CAP_SMALL_LAST_FRAME set). -2012-05-07 - 828bd08 - lavc 54.13.0 - avcodec.h +2012-05-07 - 653d117 / 828bd08 - lavc 54.20.100 / 54.13.0 - avcodec.h Add sample_rate and channel_layout fields to AVFrame. -2012-05-01 - 4010d72 - lavr 0.0.1 +2012-05-01 - 2330eb1 / 4010d72 - lavr 0.0.1 Change AV_MIX_COEFF_TYPE_Q6 to AV_MIX_COEFF_TYPE_Q8. -2012-04-25 - 3527a73 - lavu 51.29.0 - cpu.h +2012-04-25 - e890b68 / 3527a73 - lavu 51.48.100 / 51.29.0 - cpu.h Add av_parse_cpu_flags() -2012-04-24 - c8af852 - lavr 0.0.0 +2012-04-24 - 3ead79e / c8af852 - lavr 0.0.0 Add libavresample audio conversion library -2012-04-20 - 0c0d1bc - lavu 51.28.0 - audio_fifo.h +2012-04-20 - 3194ab7 / 0c0d1bc - lavu 51.47.100 / 51.28.0 - audio_fifo.h Add audio FIFO functions: av_audio_fifo_free() av_audio_fifo_alloc() @@ -282,10 +282,10 @@ API changes, most recent first: av_audio_fifo_size() av_audio_fifo_space() -2012-04-14 - lavfi 2.16.0 - avfiltergraph.h - d7bcc71 Add avfilter_graph_parse2(). +2012-04-14 - lavfi 2.70.100 / 2.16.0 - avfiltergraph.h + 7432bcf / d7bcc71 Add avfilter_graph_parse2(). -2012-04-08 - 4d693b0 - lavu 51.27.0 - samplefmt.h +2012-04-08 - 6bfb304 / 4d693b0 - lavu 51.46.100 / 51.27.0 - samplefmt.h Add av_get_packed_sample_fmt() and av_get_planar_sample_fmt() 2012-03-21 - b75c67d - lavu 51.43.100 @@ -313,73 +313,73 @@ API changes, most recent first: 2012-01-24 - 0c3577b - lavfi 2.60.100 Add avfilter_graph_dump. -2012-03-20 - 3c90cc2 - lavfo 54.2.0 +2012-03-20 - 0ebd836 / 3c90cc2 - lavfo 54.2.0 Deprecate av_read_packet(), use av_read_frame() with AVFMT_FLAG_NOPARSE | AVFMT_FLAG_NOFILLIN in AVFormatContext.flags -2012-03-05 - lavc 54.8.0 - 6699d07 Add av_get_exact_bits_per_sample() - 9524cf7 Add av_get_audio_frame_duration() +2012-03-05 - lavc 54.10.100 / 54.8.0 + f095391 / 6699d07 Add av_get_exact_bits_per_sample() + f095391 / 9524cf7 Add av_get_audio_frame_duration() -2012-03-04 - 44fe77b - lavc 54.7.0 - avcodec.h +2012-03-04 - 2af8f2c / 44fe77b - lavc 54.8.100 / 54.7.0 - avcodec.h Add av_codec_is_encoder/decoder(). -2012-03-01 - 442c132 - lavc 54.3.0 - avcodec.h +2012-03-01 - 1eb7f39 / 442c132 - lavc 54.5.100 / 54.3.0 - avcodec.h Add av_packet_shrink_side_data. -2012-02-29 - dd2a4bc - lavf 54.2.0 - avformat.h +2012-02-29 - 79ae084 / dd2a4bc - lavf 54.2.100 / 54.2.0 - avformat.h Add AVStream.attached_pic and AV_DISPOSITION_ATTACHED_PIC, used for dealing with attached pictures/cover art. -2012-02-25 - c9bca80 - lavu 51.24.0 - error.h +2012-02-25 - 305e4b3 / c9bca80 - lavu 51.41.100 / 51.24.0 - error.h Add AVERROR_UNKNOWN NOTE: this was backported to 0.8 -2012-02-20 - e9cda85 - lavc 54.2.0 +2012-02-20 - eadd426 / e9cda85 - lavc 54.2.100 / 54.2.0 Add duration field to AVCodecParserContext -2012-02-20 - 0b42a93 - lavu 51.23.1 - mathematics.h +2012-02-20 - eadd426 / 0b42a93 - lavu 51.40.100 / 51.23.1 - mathematics.h Add av_rescale_q_rnd() -2012-02-08 - 38d5533 - lavu 51.22.1 - pixdesc.h +2012-02-08 - f2b20b7 / 38d5533 - lavu 51.38.101 / 51.22.1 - pixdesc.h Add PIX_FMT_PSEUDOPAL flag. -2012-02-08 - 52f82a1 - lavc 54.01.0 +2012-02-08 - f2b20b7 / 52f82a1 - lavc 54.2.100 / 54.1.0 Add avcodec_encode_video2() and deprecate avcodec_encode_video(). -2012-02-01 - 316fc74 - lavc 54.01.0 +2012-02-01 - 4c677df / 316fc74 - lavc 54.1.0 Add av_fast_padded_malloc() as alternative for av_realloc() when aligned memory is required. The buffer will always have FF_INPUT_BUFFER_PADDING_SIZE zero-padded bytes at the end. -2012-01-31 - dd6d3b0 - lavf 54.01.0 +2012-01-31 - a369a6b / dd6d3b0 - lavf 54.1.0 Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags(). NOTE: this was backported to 0.8 -2012-01-31 - af08d9a - lavc 54.01.0 +2012-01-31 - a369a6b / af08d9a - lavc 54.1.0 Add avcodec_is_open() function. NOTE: this was backported to 0.8 -2012-01-30 - 8b93312 - lavu 51.22.0 - intfloat.h +2012-01-30 - 151ecc2 / 8b93312 - lavu 51.36.100 / 51.22.0 - intfloat.h Add a new installed header libavutil/intfloat.h with int/float punning functions. NOTE: this was backported to 0.8 -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-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 @@ -400,37 +400,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: @@ -438,55 +438,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_deinit() -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 @@ -532,31 +532,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 @@ -567,11 +567,11 @@ 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(). NOTE: this was backported to 0.7 -2011-07-10 - 0b950fe - lavc 53.8.0 +2011-07-10 - 3602ad7 / 0b950fe - lavc 53.8.0 Add avcodec_open2(), deprecate avcodec_open(). NOTE: this was backported to 0.7 @@ -614,35 +614,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 @@ -672,7 +672,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 @@ -688,10 +688,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. @@ -721,81 +721,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 @@ -816,7 +816,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 @@ -854,11 +854,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/Doxyfile b/doc/Doxyfile index 7e6d0f56fd..4b2ffb906c 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 1.1.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/doc/Makefile b/doc/Makefile index b1b4016af9..f9efe3a9c4 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -92,9 +92,9 @@ uninstall: uninstall-man uninstall-man: $(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES)) -docclean: clean +clean:: docclean -clean:: +docclean: $(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi $(RM) -r doc/doxy/html diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES index f71f18a3aa..768a747ba2 100644 --- a/doc/RELEASE_NOTES +++ b/doc/RELEASE_NOTES @@ -1,7 +1,7 @@ Release Notes ============= -* 0.10 "Freedom" January, 2012 +* 1.1 "Fire Flower" January, 2013 General notes @@ -20,3 +20,6 @@ compiler. Since MSVC does not support C99 features used extensively by FFmpeg, this has been accomplished using a converter that turns C99 code to C89. See the platform-specific documentation for more detailed documentation on building FFmpeg with MSVC. + +The used output sample format for several audio decoders has changed, make +sure you always check/use AVCodecContext.sample_fmt or AVFrame.format. diff --git a/doc/decoders.texi b/doc/decoders.texi index 2d812a27ff..cdcbe6515b 100644 --- a/doc/decoders.texi +++ b/doc/decoders.texi @@ -60,6 +60,78 @@ This decoder generates wave patterns according to predefined sequences. Its use is purely internal and the format of the data it accepts is not publicly documented. +@section libcelt + +libcelt decoder wrapper + +libcelt allows libavcodec to decode the Xiph CELT ultra-low delay audio codec. +Requires the presence of the libcelt headers and library during configuration. +You need to explicitly configure the build with @code{--enable-libcelt}. + +@section libgsm + +libgsm decoder wrapper + +libgsm allows libavcodec to decode the GSM full rate audio codec. Requires +the presence of the libgsm headers and library during configuration. You need +to explicitly configure the build with @code{--enable-libgsm}. + +This decoder supports both the ordinary GSM and the Microsoft variant. + +@section libilbc + +libilbc decoder wrapper + +libilbc allows libavcodec to decode the Internet Low Bitrate Codec (iLBC) +audio codec. Requires the presence of the libilbc headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libilbc}. + +@subsection Options + +The following option is supported by the libilbc wrapper. + +@table @option +@item enhance + +Enable the enhancement of the decoded audio when set to 1. The default +value is 0 (disabled). + +@end table + +@section libopencore-amrnb + +libopencore-amrnb decoder wrapper + +libopencore-amrnb allows libavcodec to decode the Adaptive Multi-Rate +Narrowband audio codec. Using it requires the presence of the +libopencore-amrnb headers and library during configuration. You need to +explicitly configure the build with @code{--enable-libopencore-amrnb}. + +An FFmpeg native decoder for AMR-NB exists, so users can decode AMR-NB +without this library. + +@section libopencore-amrwb + +libopencore-amrwb decoder wrapper. + +libopencore-amrwb allows libavcodec to decode the Adaptive Multi-Rate +Wideband audio codec. Using it requires the presence of the +libopencore-amrwb headers and library during configuration. You need to +explicitly configure the build with @code{--enable-libopencore-amrwb}. + +An FFmpeg native decoder for AMR-WB exists, so users can decode AMR-WB +without this library. + +@section libopus + +libopus decoder wrapper. + +libopus allows libavcodec to decode the Opus Interactive Audio Codec. +Requires the presence of the libopus headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libopus}. + @c man end AUDIO DECODERS @chapter Subtitles Decoders diff --git a/doc/developer.texi b/doc/developer.texi index e75f3b9403..be1b62a3f3 100644 --- a/doc/developer.texi +++ b/doc/developer.texi @@ -190,8 +190,8 @@ set shiftwidth=4 set softtabstop=4 set cindent set cinoptions=(0 -" 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/encoders.texi b/doc/encoders.texi index a5325f45a8..22c125743a 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -25,6 +25,95 @@ enabled encoders. A description of some of the currently available audio encoders follows. +@anchor{aacenc} +@section aac + +Advanced Audio Coding (AAC) encoder. + +This encoder is an experimental FFmpeg-native AAC encoder. Currently only the +low complexity (AAC-LC) profile is supported. To use this encoder, you must set +@option{strict} option to @samp{experimental} or lower. + +As this encoder is experimental, unexpected behavior may exist from time to +time. For a more stable AAC encoder, see @ref{libvo-aacenc}. However, be warned +that it has a worse quality reported by some users. + +@c Comment this out until somebody writes the respective documentation. +@c See also @ref{libfaac}, @ref{libaacplus}, and @ref{libfdk-aac-enc}. + +@subsection Options + +@table @option +@item b +Set bit rate in bits/s. Setting this automatically activates constant bit rate +(CBR) mode. + +@item q +Set quality for variable bit rate (VBR) mode. This option is valid only using +the @command{ffmpeg} command-line tool. For library interface users, use +@option{global_quality}. + +@item stereo_mode +Set stereo encoding mode. Possible values: + +@table @samp +@item auto +Automatically selected by the encoder. + +@item ms_off +Disable middle/side encoding. This is the default. + +@item ms_force +Force middle/side encoding. +@end table + +@item aac_coder +Set AAC encoder coding method. Possible values: + +@table @samp +@item 0 +FAAC-inspired method. + +This method is a simplified reimplementation of the method used in FAAC, which +sets thresholds proportional to the band energies, and then decreases all the +thresholds with quantizer steps to find the appropriate quantization with +distortion below threshold band by band. + +The quality of this method is comparable to the two loop searching method +descibed below, but somewhat a little better and slower. + +@item 1 +Average noise to mask ratio (ANMR) trellis-based solution. + +This has a theoretic best quality out of all the coding methods, but at the +cost of the slowest speed. + +@item 2 +Two loop searching (TLS) method. + +This method first sets quantizers depending on band thresholds and then tries +to find an optimal combination by adding or subtracting a specific value from +all quantizers and adjusting some individual quantizer a little. + +This method produces similar quality with the FAAC method and is the default. + +@item 3 +Constant quantizer method. + +This method sets a constant quantizer for all bands. This is the fastest of all +the methods, yet produces the worst quality. + +@end table + +@end table + +@subsection Tips and Tricks + +According to some reports +(e.g. @url{http://d.hatena.ne.jp/kamedo2/20120729/1343545890}), setting the +@option{cutoff} option to 15000 Hz greatly improves the quality of the output +quality. As a result, we encourage you to do the same. + @section ac3 and ac3_fixed AC-3 audio encoders. @@ -412,6 +501,279 @@ Selected by Encoder (default) @end table +@section libmp3lame + +LAME (Lame Ain't an MP3 Encoder) MP3 encoder wrapper + +Requires the presence of the libmp3lame headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libmp3lame}. + +@subsection Options + +The following options are supported by the libmp3lame wrapper. The +@command{lame}-equivalent of the options are listed in parentheses. + +@table @option +@item b (@emph{-b}) +Set bitrate expressed in bits/s for CBR. LAME @code{bitrate} is +expressed in kilobits/s. + +@item q (@emph{-V}) +Set constant quality setting for VBR. This option is valid only +using the @command{ffmpeg} command-line tool. For library interface +users, use @option{global_quality}. + +@item compression_level (@emph{-q}) +Set algorithm quality. Valid arguments are integers in the 0-9 range, +with 0 meaning highest quality but slowest, and 9 meaning fastest +while producing the worst quality. + +@item reservoir +Enable use of bit reservoir when set to 1. Default value is 1. LAME +has this enabled by default, but can be overriden by use +@option{--nores} option. + +@end table + +@section libopencore-amrnb + +OpenCORE Adaptive Multi-Rate Narrowband encoder. + +Requires the presence of the libopencore-amrnb headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libopencore-amrnb --enable-version3}. + +This is a mono-only encoder. Officially it only supports 8000Hz sample rate, +but you can override it by setting @option{strict} to @samp{unofficial} or +lower. + +@subsection Options + +@table @option + +@item b +Set bitrate in bits per second. Only the following bitrates are supported, +otherwise libavcodec will round to the nearest valid bitrate. + +@table @option +@item 4750 +@item 5150 +@item 5900 +@item 6700 +@item 7400 +@item 7950 +@item 10200 +@item 12200 +@end table + +@item dtx +Allow discontinuous transmission (generate comfort noise) when set to 1. The +default value is 0 (disabled). + +@end table + +@section libtwolame + +TwoLAME MP2 encoder wrapper + +Requires the presence of the libtwolame headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libtwolame}. + +@subsection Options + +The following options are supported by the libtwolame wrapper. The +@command{twolame}-equivalent options follow the FFmpeg ones and are in +parentheses. + +@table @option +@item b (@emph{-b}) +Set bitrate expressed in bits/s for CBR. @command{twolame} @option{b} +option is expressed in kilobits/s. Default value is 128k. + +@item q (@emph{-V}) +Set quality for experimental VBR support. Maximum value range is +from -50 to 50, useful range is from -10 to 10. The higher the +value, the better the quality. This option is valid only using the +@command{ffmpeg} command-line tool. For library interface users, +use @option{global_quality}. + +@item mode (@emph{--mode}) +Set the mode of the resulting audio. Possible values: + +@table @samp +@item auto +Choose mode automatically based on the input. This is the default. +@item stereo +Stereo +@item joint_stereo +Joint stereo +@item dual_channel +Dual channel +@item mono +Mono +@end table + +@item psymodel (@emph{--psyc-mode}) +Set psychoacoustic model to use in encoding. The argument must be +an integer between -1 and 4, inclusive. The higher the value, the +better the quality. The default value is 3. + +@item energy_levels (@emph{--energy}) +Enable energy levels extensions when set to 1. The default value is +0 (disabled). + +@item error_protection (@emph{--protect}) +Enable CRC error protection when set to 1. The default value is 0 +(disabled). + +@item copyright (@emph{--copyright}) +Set MPEG audio copyright flag when set to 1. The default value is 0 +(disabled). + +@item original (@emph{--original}) +Set MPEG audio original flag when set to 1. The default value is 0 +(disabled). + +@end table + +@anchor{libvo-aacenc} +@section libvo-aacenc + +VisualOn AAC encoder + +Requires the presence of the libvo-aacenc headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libvo-aacenc --enable-version3}. + +This encoder is considered to be worse than the +@ref{aacenc,,native experimental FFmpeg AAC encoder}, according to +multiple sources. + +@subsection Options + +The VisualOn AAC encoder only support encoding AAC-LC and up to 2 +channels. It is also CBR-only. + +@table @option + +@item b +Set bit rate in bits/s. + +@end table + +@section libvo-amrwbenc + +VisualOn Adaptive Multi-Rate Wideband encoder + +Requires the presence of the libvo-amrwbenc headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libvo-amrwbenc --enable-version3}. + +This is a mono-only encoder. Officially it only supports 16000Hz sample +rate, but you can override it by setting @option{strict} to +@samp{unofficial} or lower. + +@subsection Options + +@table @option + +@item b +Set bitrate in bits/s. Only the following bitrates are supported, otherwise +libavcodec will round to the nearest valid bitrate. + +@table @samp +@item 6600 +@item 8850 +@item 12650 +@item 14250 +@item 15850 +@item 18250 +@item 19850 +@item 23050 +@item 23850 +@end table + +@item dtx +Allow discontinuous transmission (generate comfort noise) when set to 1. The +default value is 0 (disabled). + +@end table + +@section libopus + +libopus Opus Interactive Audio Codec encoder wrapper. + +Requires the presence of the libopus headers and library during +configuration. You need to explicitly configure the build with +@code{--enable-libopus}. + +@subsection Option Mapping + +Most libopus options are modeled after the @command{opusenc} utility from +opus-tools. The following is an option mapping chart describing options +supported by the libopus wrapper, and their @command{opusenc}-equivalent +in parentheses. + +@table @option + +@item b (@emph{bitrate}) +Set the bit rate in bits/s. FFmpeg's @option{b} option is +expressed in bits/s, while @command{opusenc}'s @option{bitrate} in +kilobits/s. + +@item vbr (@emph{vbr}, @emph{hard-cbr}, and @emph{cvbr}) +Set VBR mode. The FFmpeg @option{vbr} option has the following +valid arguments, with the their @command{opusenc} equivalent options +in parentheses: + +@table @samp +@item off (@emph{hard-cbr}) +Use constant bit rate encoding. + +@item on (@emph{vbr}) +Use variable bit rate encoding (the default). + +@item constrained (@emph{cvbr}) +Use constrained variable bit rate encoding. +@end table + +@item compression_level (@emph{comp}) +Set encoding algorithm complexity. Valid options are integers in +the 0-10 range. 0 gives the fastest encodes but lower quality, while 10 +gives the highest quality but slowest encoding. The default is 10. + +@item frame_duration (@emph{framesize}) +Set maximum frame size, or duration of a frame in milliseconds. The +argument must be exactly the following: 2.5, 5, 10, 20, 40, 60. Smaller +frame sizes achieve lower latency but less quality at a given bitrate. +Sizes greater than 20ms are only interesting at fairly low bitrates. +The default is 20ms. + +@item packet_loss (@emph{expect-loss}) +Set expected packet loss percentage. The default is 0. + +@item application (N.A.) +Set intended application type. Valid options are listed below: + +@table @samp +@item voip +Favor improved speech intelligibility. +@item audio +Favor faithfulness to the input (the default). +@item lowdelay +Restrict to only the lowest delay modes. +@end table + +@item cutoff (N.A.) +Set cutoff bandwidth in Hz. The argument must be exactly one of the +following: 4000, 6000, 8000, 12000, or 20000, corresponding to +narrowband, mediumband, wideband, super wideband, and fullband +respectively. The default is 0 (cutoff disabled). + +@end table + @c man end AUDIO ENCODERS @chapter Video Encoders @@ -633,4 +995,117 @@ ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv For more information about libx264 and the supported options see: @url{http://www.videolan.org/developers/x264.html} +@section libxvid + +Xvid MPEG-4 Part 2 encoder wrapper. + +This encoder requires the presence of the libxvidcore headers and library +during configuration. You need to explicitly configure the build with +@code{--enable-libxvid --enable-gpl}. + +The native @code{mpeg4} encoder supports the MPEG-4 Part 2 format, so +users can encode to this format without this library. + +@subsection Options + +The following options are supported by the libxvid wrapper. Some of +the following options are listed but are not documented, and +correspond to shared codec options. See @ref{codec-options,,the Codec +Options chapter} for their documentation. The other shared options +which are not listed have no effect for the libxvid encoder. + +@table @option +@item b + +@item g + +@item qmin + +@item qmax + +@item mpeg_quant + +@item threads + +@item bf + +@item b_qfactor + +@item b_qoffset + +@item flags +Set specific encoding flags. Possible values: + +@table @samp + +@item mv4 +Use four motion vector by macroblock. + +@item aic +Enable high quality AC prediction. + +@item gray +Only encode grayscale. + +@item gmc +Enable the use of global motion compensation (GMC). + +@item qpel +Enable quarter-pixel motion compensation. + +@item cgop +Enable closed GOP. + +@item global_header +Place global headers in extradata instead of every keyframe. + +@end table + +@item trellis + +@item me_method +Set motion estimation method. Possible values in decreasing order of +speed and increasing order of quality: + +@table @samp +@item zero +Use no motion estimation (default). + +@item phods +@item x1 +@item log +Enable advanced diamond zonal search for 16x16 blocks and half-pixel +refinement for 16x16 blocks. @samp{x1} and @samp{log} are aliases for +@samp{phods}. + +@item epzs +Enable all of the things described above, plus advanced diamond zonal +search for 8x8 blocks, half-pixel refinement for 8x8 blocks, and motion +estimation on chroma planes. + +@item full +Enable all of the things described above, plus extended 16x16 and 8x8 +blocks search. +@end table + +@item mbd +Set macroblock decision algorithm. Possible values in the increasing +order of quality: + +@table @samp +@item simple +Use macroblock comparing function algorithm (default). + +@item bits +Enable rate distortion-based half pixel and quarter pixel refinement for +16x16 blocks. + +@item rd +Enable all of the things described above, plus rate distortion-based +half pixel and quarter pixel refinement for 8x8 blocks, and rate +distortion-based search using square pattern. +@end table + +@end table + @c man end VIDEO ENCODERS diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c index 3c9d4a1278..bee21b7b33 100644 --- a/doc/examples/demuxing.c +++ b/doc/examples/demuxing.c @@ -314,7 +314,7 @@ int main (int argc, char **argv) if (audio_stream) { const char *fmt; - if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt) < 0)) + if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 0) goto end; printf("Play the output audio file with the command:\n" "ffplay -f %s -ac %d -ar %d %s\n", diff --git a/doc/examples/resampling_audio.c b/doc/examples/resampling_audio.c index 9075719a37..dd128e8d6e 100644 --- a/doc/examples/resampling_audio.c +++ b/doc/examples/resampling_audio.c @@ -200,7 +200,7 @@ int main(int argc, char **argv) fwrite(dst_data[0], 1, dst_bufsize, dst_file); } while (t < 10); - if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt) < 0)) + if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0) goto end; fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n" "ffplay -f %s -channel_layout %"PRId64" -channels %d -ar %d %s\n", diff --git a/doc/ffmpeg-codecs.texi b/doc/ffmpeg-codecs.texi index b6d123a7da..e94c216ac3 100644 --- a/doc/ffmpeg-codecs.texi +++ b/doc/ffmpeg-codecs.texi @@ -17,6 +17,7 @@ the libavcodec library. @c man end DESCRIPTION +@anchor{codec-options} @chapter Codec Options @c man begin CODEC OPTIONS diff --git a/doc/ffmpeg-formats.texi b/doc/ffmpeg-formats.texi index 03e4f30ac3..4d9038698e 100644 --- a/doc/ffmpeg-formats.texi +++ b/doc/ffmpeg-formats.texi @@ -140,6 +140,12 @@ Use wallclock as timestamps. @item avoid_negative_ts @var{integer} (@emph{output}) Shift timestamps to make them positive. 1 enables, 0 disables, default of -1 enables when required by target format. + +@item skip_initial_bytes @var{integer} (@emph{input}) +Set number initial bytes to skip. Default is 0. + +@item correct_ts_overflow @var{integer} (@emph{input}) +Correct single timestamp overflows if set to 1. Default is 1. @end table @c man end FORMAT OPTIONS diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index d0fe327c15..415491d363 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -978,7 +978,7 @@ ffmpeg -filter_complex 'color=red' -t 5 out.mkv As a special exception, you can use a bitmap subtitle stream as input: it will be converted into a video with the same size as the largest video in -the file, or 720×576 if no video is present. Note that this is an +the file, or 720x576 if no video is present. Note that this is an experimental and temporary solution. It will be removed once libavfilter has proper support for subtitles. @@ -1254,11 +1254,11 @@ ffmpeg -f image2 -pattern_type glob -i 'foo-*.jpeg' -r 12 -s WxH foo.avi You can put many streams of the same type in the output: @example -ffmpeg -i test1.avi -i test2.avi -map 0:3 -map 0:2 -map 0:1 -map 0:0 -c copy test12.nut +ffmpeg -i test1.avi -i test2.avi -map 1:1 -map 1:0 -map 0:1 -map 0:0 -c copy -y test12.nut @end example -The resulting output file @file{test12.avi} will contain first four streams from -the input file in reverse order. +The resulting output file @file{test12.nut} will contain the first four streams +from the input files in reverse order. @item To force CBR video output: diff --git a/doc/filters.texi b/doc/filters.texi index da7e816364..ce7bbb45f8 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3,10 +3,10 @@ Filtering in FFmpeg is enabled through the libavfilter library. -In libavfilter, it is possible for filters to have multiple inputs and -multiple outputs. -To illustrate the sorts of things that are possible, we can -use a complex filter graph. For example, the following one: +In libavfilter, a filter can have multiple inputs and multiple +outputs. +To illustrate the sorts of things that are possible, we consider the +following filtergraph. @example input --> split ---------------------> overlay --> output @@ -15,25 +15,32 @@ input --> split ---------------------> overlay --> output +-----> crop --> vflip -------+ @end example -splits the stream in two streams, sends one stream through the crop filter -and the vflip filter before merging it back with the other stream by -overlaying it on top. You can use the following command to achieve this: +This filtergraph splits the input stream in two streams, sends one +stream through the crop filter and the vflip filter before merging it +back with the other stream by overlaying it on top. You can use the +following command to achieve this: @example -ffmpeg -i input -vf "[in] split [T1], [T2] overlay=0:H/2 [out]; [T1] crop=iw:ih/2:0:ih/2, vflip [T2]" output +ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT @end example The result will be that in output the top half of the video is mirrored onto the bottom half. -Filters are loaded using the @var{-vf} or @var{-af} option passed to -@command{ffmpeg} or to @command{ffplay}. Filters in the same linear -chain are separated by commas. In our example, @var{split, -overlay} are in one linear chain, and @var{crop, vflip} are in -another. The points where the linear chains join are labeled by names -enclosed in square brackets. In our example, that is @var{[T1]} and -@var{[T2]}. The special labels @var{[in]} and @var{[out]} are the points -where video is input and output. +Filters in the same linear chain are separated by commas, and distinct +linear chains of filters are separated by semicolons. In our example, +@var{crop,vflip} are in one linear chain, @var{split} and +@var{overlay} are separately in another. The points where the linear +chains join are labelled by names enclosed in square brackets. In the +example, the split filter generates two outputs that are associated to +the labels @var{[main]} and @var{[tmp]}. + +The stream sent to the second output of @var{split}, labelled as +@var{[tmp]}, is processed through the @var{crop} filter, which crops +away the lower half part of the video, and then vertically flipped. The +@var{overlay} filter takes in input the first unchanged output of the +split filter (which was labelled as @var{[main]}), and overlay on its +lower half the output generated by the @var{crop,vflip} filterchain. Some filters take in input a list of parameters: they are specified after the filter name and an equal sign, and are separated from each other @@ -179,7 +186,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} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] @end example @@ -4149,7 +4156,7 @@ Alternatively, the options can be specified as a flat string: @var{layout}[:@var{nb_frames}[:@var{margin}[:@var{padding}]]] -For example, produce 8×8 PNG tiles of all keyframes (@option{-skip_frame +For example, produce 8x8 PNG tiles of all keyframes (@option{-skip_frame nokey}) in a movie: @example ffmpeg -skip_frame nokey -i file.avi -vf 'scale=128:72,tile=8x8' -an -vsync 0 keyframes%03d.png @@ -5543,7 +5550,7 @@ Activate unsafe mode: do not fail if segments have a different format. The filter has @var{v}+@var{a} outputs: first @var{v} video outputs, then @var{a} audio outputs. -There are @var{n}×(@var{v}+@var{a}) inputs: first the inputs for the first +There are @var{n}x(@var{v}+@var{a}) inputs: first the inputs for the first segment, in the same order as the outputs, then the inputs for the second segment, etc. diff --git a/doc/general.texi b/doc/general.texi index cdbcf8407e..200ea1a3f5 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -24,7 +24,7 @@ instructions. To enable using OpenJPEG in FFmpeg, pass @code{--enable-libopenjp @file{./configure}. -@section OpenCORE and VisualOn libraries +@section OpenCORE, VisualOn, and Fraunhofer libraries Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer libraries provide encoders for a number of audio codecs. @@ -32,9 +32,14 @@ libraries provide encoders for a number of audio codecs. @float NOTE OpenCORE and VisualOn libraries are under the Apache License 2.0 (see @url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is -incompatible with the LGPL version 2.1 and GPL version 2. You have to +incompatible to the LGPL version 2.1 and GPL version 2. You have to upgrade FFmpeg's license to LGPL version 3 (or if you have enabled -GPL components, GPL version 3) to use it. +GPL components, GPL version 3) by passing @code{--enable-version3} to configure in +order to use it. + +The Fraunhofer AAC library is licensed under a license incompatible to the GPL +and is not known to be compatible to the LGPL. Therefore, you have to pass +@code{--enable-nonfree} to configure to use it. @end float @subsection OpenCORE AMR 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/muxers.texi b/doc/muxers.texi index fb642847e1..33cbb7859e 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -18,6 +18,23 @@ enabled muxers. A description of some of the currently available muxers follows. +@anchor{aiff} +@section aiff + +Audio Interchange File Format muxer. + +It accepts the following options: + +@table @option +@item write_id3v2 +Enable ID3v2 tags writing when set to 1. Default is 0 (disabled). + +@item id3v2_version +Select ID3v2 version to write. Currently only version 3 and 4 (aka. +ID3v2.3 and ID3v2.4) are supported. The default is version 4. + +@end table + @anchor{crc} @section crc @@ -711,10 +728,11 @@ Write an mp3 with an ID3v2.3 header and an ID3v1 footer: ffmpeg -i INPUT -id3v2_version 3 -write_id3v1 1 out.mp3 @end example -Attach a picture to an mp3: +To attach a picture to an mp3 file select both the audio and the picture stream +with @code{map}: @example -ffmpeg -i input.mp3 -i cover.png -c copy -metadata:s:v title="Album cover" --metadata:s:v comment="Cover (Front)" out.mp3 +ffmpeg -i input.mp3 -i cover.png -c copy -map 0 -map 1 +-metadata:s:v title="Album cover" -metadata:s:v comment="Cover (Front)" out.mp3 @end example @c man end MUXERS diff --git a/doc/platform.texi b/doc/platform.texi index dcdfff20d7..39af15a5d6 100644 --- a/doc/platform.texi +++ b/doc/platform.texi @@ -51,8 +51,9 @@ 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{https://github.com/FFmpeg/gas-preprocessor} or @url{http://github.com/yuvi/gas-preprocessor} to build the optimized -assembler functions. Just download the Perl script and put it somewhere +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 @@ -114,7 +115,7 @@ wrapper. You will need the following prerequisites: @itemize -@item @uref{https://github.com/libav/c99-to-c89/, C99-to-C89 Converter & Wrapper} +@item @uref{http://download.videolan.org/pub/contrib/c99-to-c89/, C99-to-C89 Converter & Wrapper} @item @uref{http://code.google.com/p/msinttypes/, msinttypes} @item @uref{http://www.mingw.org/, MSYS} @item @uref{http://yasm.tortall.net/, YASM} diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl index 8790563131..610f349afb 100755 --- a/doc/texi2pod.pl +++ b/doc/texi2pod.pl @@ -121,7 +121,7 @@ INF: while(<$inf>) { $chapters{$chapter_name} .= postprocess($chapter) if ($chapter_name); # start new chapter - $chapter_name = $1, push (@chapters_sequence, $chapter_name); + $chapter_name = $1, push (@chapters_sequence, $chapter_name) unless $skipping; $chapters{$chapter_name} = "" unless exists $chapters{$chapter_name}; $chapter = ""; $output = 1; @@ -169,7 +169,7 @@ INF: while(<$inf>) { } elsif ($ended =~ /^(?:example|smallexample|display)$/) { $shift = ""; $_ = ""; # need a paragraph break - } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) { + } elsif ($ended =~ /^(?:itemize|enumerate|(?:multi|[fv])?table)$/) { $_ = "\n=back\n"; $ic = pop @icstack; } else { @@ -269,7 +269,7 @@ INF: while(<$inf>) { $endw = "enumerate"; }; - /^\@([fv]?table)\s+(\@[a-z]+)/ and do { + /^\@((?:multi|[fv])?table)\s+(\@[a-z]+)/ and do { push @endwstack, $endw; push @icstack, $ic; $endw = $1; @@ -278,6 +278,7 @@ INF: while(<$inf>) { $ic =~ s/\@(?:code|kbd)/C/; $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/; $ic =~ s/\@(?:file)/F/; + $ic =~ s/\@(?:columnfractions)//; $_ = "\n=over 4\n"; }; @@ -288,6 +289,21 @@ INF: while(<$inf>) { $_ = ""; # need a paragraph break }; + /^\@item\s+(.*\S)\s*$/ and $endw eq "multitable" and do { + my $columns = $1; + $columns =~ s/\@tab/ : /; + + $_ = "\n=item B<". $columns .">\n"; + }; + + /^\@tab\s+(.*\S)\s*$/ and $endw eq "multitable" and do { + my $columns = $1; + $columns =~ s/\@tab/ : /; + + $_ = " : ". $columns; + $chapter =~ s/\n+\s+$//; + }; + /^\@itemx?\s*(.+)?$/ and do { if (defined $1) { # Entity escapes prevent munging by the <> processing below. @@ -361,6 +377,7 @@ sub postprocess s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g; s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g; s/;\s+\@pxref\{(?:[^\}]*)\}//g; + s/\@ref\{(?:[^,\}]*,)(?:[^,\}]*,)([^,\}]*).*\}/$1/g; s/\@ref\{([^\}]*)\}/$1/g; s/\@noindent\s*//g; s/\@refill//g; diff --git a/ffmpeg.c b/ffmpeg.c index acaa523170..611d6a8277 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -152,6 +152,8 @@ static struct termios oldtty; static int restore_tty; #endif +static void free_input_threads(void); + /* sub2video hack: Convert subtitles to video with alpha to insert them in filter graphs. @@ -441,6 +443,9 @@ static void exit_program(void) av_freep(&output_streams[i]->logfile_prefix); av_freep(&output_streams[i]); } +#if HAVE_PTHREADS + free_input_threads(); +#endif for (i = 0; i < nb_input_files; i++) { avformat_close_input(&input_files[i]->ctx); av_freep(&input_files[i]); @@ -471,7 +476,6 @@ static void exit_program(void) if (received_sigterm) { av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n", (int) received_sigterm); - exit (255); } } @@ -574,6 +578,25 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) bsfc = bsfc->next; } + if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) && + ost->last_mux_dts != AV_NOPTS_VALUE && + pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) { + av_log(NULL, AV_LOG_WARNING, "Non-monotonous DTS in output stream " + "%d:%d; previous: %"PRId64", current: %"PRId64"; ", + ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts); + if (exit_on_error) { + av_log(NULL, AV_LOG_FATAL, "aborting.\n"); + exit(1); + } + av_log(NULL, AV_LOG_WARNING, "changing to %"PRId64". This may result " + "in incorrect timestamps in the output file.\n", + ost->last_mux_dts + 1); + pkt->dts = ost->last_mux_dts + 1; + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts = FFMAX(pkt->pts, pkt->dts); + } + ost->last_mux_dts = pkt->dts; + pkt->stream_index = ost->index; if (debug_ts) { @@ -992,6 +1015,19 @@ static void do_video_stats(OutputStream *ost, int frame_size) } } +static void finish_output_stream(OutputStream *ost) +{ + OutputFile *of = output_files[ost->file_index]; + int i; + + ost->finished = 1; + + if (of->shortest) { + for (i = 0; i < of->ctx->nb_streams; i++) + output_streams[of->ost_index + i]->finished = 1; + } +} + /** * Get and encode new output from any of the filtergraphs, without causing * activity. @@ -1655,7 +1691,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) if (!frame_sample_aspect->num) *frame_sample_aspect = ist->st->sample_aspect_ratio; - if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER && !changed) { + if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER && !changed && !do_deinterlace) { FrameBuffer *buf = decoded_frame->opaque; AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays( decoded_frame->data, decoded_frame->linesize, @@ -1984,7 +2020,7 @@ static int transcode_init(void) AVCodecContext *codec; OutputStream *ost; InputStream *ist; - char error[1024]; + char error[1024] = {0}; int want_sdp = 1; /* init framerate emulation */ @@ -2100,6 +2136,12 @@ static int transcode_init(void) codec->time_base.num *= icodec->ticks_per_frame; } } + if ( codec->codec_tag == AV_RL32("tmcd") + && icodec->time_base.num < icodec->time_base.den + && icodec->time_base.num > 0 + && 121LL*icodec->time_base.num > icodec->time_base.den) { + codec->time_base = icodec->time_base; + } if(ost->frame_rate.num) codec->time_base = av_inv_q(ost->frame_rate); @@ -2754,7 +2796,7 @@ static int process_input(int file_index) if (ost->source_index == ifile->ist_index + i && (ost->stream_copy || ost->enc->type == AVMEDIA_TYPE_SUBTITLE)) - close_output_stream(ost); + finish_output_stream(ost); } } @@ -3214,6 +3256,6 @@ int main(int argc, char **argv) printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss); } - exit(0); + exit(received_nb_signals ? 255 : 0); return 0; } diff --git a/ffmpeg.h b/ffmpeg.h index 1260563cb8..564d305d6b 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -300,6 +300,8 @@ typedef struct OutputStream { /* pts of the first frame encoded for this stream, used for limiting * recording time */ int64_t first_pts; + /* dts of the last packet sent to the muxer */ + int64_t last_mux_dts; AVBitStreamFilterContext *bitstream_filters; AVCodec *enc; int64_t max_frames; diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 60309307c5..7672bc1f60 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -41,12 +41,15 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum AVPixelFo const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target); int has_alpha = desc ? desc->nb_components % 2 == 0 : 0; enum AVPixelFormat best= AV_PIX_FMT_NONE; + const enum AVPixelFormat mjpeg_formats[] = { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }; + const enum AVPixelFormat ljpeg_formats[] = { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE }; + if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { if (st->codec->codec_id == AV_CODEC_ID_MJPEG) { - p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }; + p = mjpeg_formats; } else if (st->codec->codec_id == AV_CODEC_ID_LJPEG) { - p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE }; + p =ljpeg_formats; } } for (; *p != AV_PIX_FMT_NONE; p++) { diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 63e3de959f..a8dacf1b71 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -1021,6 +1021,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e input_streams[source_index]->discard = 0; input_streams[source_index]->st->discard = AVDISCARD_NONE; } + ost->last_mux_dts = AV_NOPTS_VALUE; return ost; } @@ -1143,8 +1144,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in 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) @@ -1155,9 +1154,11 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in 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); } } @@ -1824,7 +1825,8 @@ static int opt_target(void *optctx, 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) { @@ -1938,6 +1940,10 @@ static int opt_target(void *optctx, const char *opt, const char *arg) av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg); return AVERROR(EINVAL); } + + av_dict_copy(&o->g->codec_opts, codec_opts, 0); + av_dict_copy(&o->g->format_opts, format_opts, 0); + return 0; } @@ -2150,7 +2156,7 @@ static int opt_channel_layout(void *optctx, const char *opt, const char *arg) return AVERROR(EINVAL); } snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout); - ret = opt_default(NULL, opt, layout_str); + ret = opt_default_new(o, opt, layout_str); if (ret < 0) return ret; diff --git a/ffserver.c b/ffserver.c index f2cf67f694..9b2ce990d2 100644 --- a/ffserver.c +++ b/ffserver.c @@ -328,6 +328,14 @@ static AVLFG random_state; static FILE *logfile = NULL; +static void htmlstrip(char *s) { + while (s && *s) { + s += strspn(s, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,. "); + if (*s) + *s++ = '?'; + } +} + static int64_t ffm_read_write_index(int fd) { uint8_t buf[8]; @@ -1887,6 +1895,7 @@ static int http_parse_request(HTTPContext *c) send_error: c->http_error = 404; q = c->buffer; + htmlstrip(msg); snprintf(q, c->buffer_size, "HTTP/1.0 404 Not Found\r\n" "Content-type: text/html\r\n" diff --git a/libavcodec/012v.c b/libavcodec/012v.c index b2c2790193..58c76ab5d9 100644 --- a/libavcodec/012v.c +++ b/libavcodec/012v.c @@ -44,7 +44,7 @@ static av_cold int zero12v_decode_init(AVCodecContext *avctx) static int zero12v_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - int line = 0; + int line, ret; const int width = avctx->width; AVFrame *pic = avctx->coded_frame; uint16_t *y, *u, *v; @@ -54,8 +54,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, if (pic->data[0]) avctx->release_buffer(avctx, pic); - if (width == 1) { - av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n"); + if (width <= 1 || avctx->height <= 0) { + av_log(avctx, AV_LOG_ERROR, "Dimensions %dx%d not supported.\n", width, avctx->height); return AVERROR_INVALIDDATA; } if (avpkt->size < avctx->height * stride) { @@ -65,48 +65,48 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, } pic->reference = 0; - if (ff_get_buffer(avctx, pic) < 0) - return AVERROR_INVALIDDATA;; + if ((ret = ff_get_buffer(avctx, pic)) < 0) + return ret; - y = (uint16_t *)pic->data[0]; - u = (uint16_t *)pic->data[1]; - v = (uint16_t *)pic->data[2]; line_end = avpkt->data + stride; + for (line = 0; line < avctx->height; line++) { + uint16_t y_temp[6] = {0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000}; + uint16_t u_temp[3] = {0x8000, 0x8000, 0x8000}; + uint16_t v_temp[3] = {0x8000, 0x8000, 0x8000}; + int x; + y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); + u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); + v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); - while (line++ < avctx->height) { - while (1) { - uint32_t t = AV_RL32(src); + for (x = 0; x < width; x += 6) { + uint32_t t; + + if (width - x < 6 || line_end - src < 16) { + y = y_temp; + u = u_temp; + v = v_temp; + } + + if (line_end - src < 4) + break; + + t = AV_RL32(src); src += 4; *u++ = t << 6 & 0xFFC0; *y++ = t >> 4 & 0xFFC0; *v++ = t >> 14 & 0xFFC0; - if (src >= line_end - 1) { - *y = 0x80; - src++; - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + if (line_end - src < 4) break; - } t = AV_RL32(src); src += 4; *y++ = t << 6 & 0xFFC0; *u++ = t >> 4 & 0xFFC0; *y++ = t >> 14 & 0xFFC0; - if (src >= line_end - 2) { - if (!(width & 1)) { - *y = 0x80; - src += 2; - } - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + + if (line_end - src < 4) break; - } t = AV_RL32(src); src += 4; @@ -114,15 +114,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, *y++ = t >> 4 & 0xFFC0; *u++ = t >> 14 & 0xFFC0; - if (src >= line_end - 1) { - *y = 0x80; - src++; - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + if (line_end - src < 4) break; - } t = AV_RL32(src); src += 4; @@ -130,18 +123,21 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, *v++ = t >> 4 & 0xFFC0; *y++ = t >> 14 & 0xFFC0; - if (src >= line_end - 2) { - if (width & 1) { - *y = 0x80; - src += 2; - } - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + if (width - x < 6) break; - } } + + if (x < width) { + y = x + (uint16_t *)(pic->data[0] + line * pic->linesize[0]); + u = x/2 + (uint16_t *)(pic->data[1] + line * pic->linesize[1]); + v = x/2 + (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + memcpy(y, y_temp, sizeof(*y) * (width - x)); + memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2); + memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2); + } + + line_end += stride; + src = line_end - stride; } *got_frame = 1; diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index c7e3c68ccf..fa663a7659 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -328,12 +328,12 @@ static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w, } break; default: - av_assert2(0); + av_assert0(0); } } -static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, - int log2w, int log2h, int stride) +static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, + int log2w, int log2h, int stride) { const int index = size2index[log2h][log2w]; const int h = 1 << log2h; @@ -342,57 +342,72 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, BLOCK_TYPE_VLC_BITS, 1); uint16_t *start = (uint16_t *)f->last_picture.data[0]; uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w); + int ret; - av_assert2(code >= 0 && code <= 6); + av_assert0(code >= 0 && code <= 6 && log2w >= 0); if (code == 0) { if (bytestream2_get_bytes_left(&f->g) < 1) { av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); - return; + return AVERROR_INVALIDDATA; } src += f->mv[bytestream2_get_byteu(&f->g)]; if (start > src || src > end) { av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); - return; + return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 1, 0); } else if (code == 1) { log2h--; - decode_p_block(f, dst, src, log2w, log2h, stride); - decode_p_block(f, dst + (stride << log2h), - src + (stride << log2h), log2w, log2h, stride); + if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0) + return ret; + if ((ret = decode_p_block(f, dst + (stride << log2h), + src + (stride << log2h), + log2w, log2h, stride)) < 0) + return ret; } else if (code == 2) { log2w--; - decode_p_block(f, dst , src, log2w, log2h, stride); - decode_p_block(f, dst + (1 << log2w), - src + (1 << log2w), log2w, log2h, stride); + if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0) + return ret; + if ((ret = decode_p_block(f, dst + (1 << log2w), + src + (1 << log2w), + log2w, log2h, stride)) < 0) + return ret; } else if (code == 3 && f->version < 2) { + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return AVERROR_INVALIDDATA; + } mcdc(dst, src, log2w, h, stride, 1, 0); } else if (code == 4) { if (bytestream2_get_bytes_left(&f->g) < 1) { av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); - return; + return AVERROR_INVALIDDATA; } src += f->mv[bytestream2_get_byteu(&f->g)]; if (start > src || src > end) { av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); - return; + return AVERROR_INVALIDDATA; } if (bytestream2_get_bytes_left(&f->g2) < 2){ av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); - return; + return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2)); } else if (code == 5) { if (bytestream2_get_bytes_left(&f->g2) < 2) { av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); - return; + return AVERROR_INVALIDDATA; + } + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2)); } else if (code == 6) { if (bytestream2_get_bytes_left(&f->g2) < 4) { av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); - return; + return AVERROR_INVALIDDATA; } if (log2w) { dst[0] = bytestream2_get_le16u(&f->g2); @@ -402,6 +417,7 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, dst[stride] = bytestream2_get_le16u(&f->g2); } } + return 0; } static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) @@ -414,8 +430,20 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) const int stride = f->current_picture.linesize[0] >> 1; unsigned int bitstream_size, bytestream_size, wordstream_size, extra, bytestream_offset, wordstream_offset; + int ret; + + if (!f->last_picture.data[0]) { + if ((ret = ff_get_buffer(f->avctx, &f->last_picture)) < 0) { + av_log(f->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + for (y=0; yavctx->height; y++) + memset(f->last_picture.data[0] + y*f->last_picture.linesize[0], 0, 2*f->avctx->width); + } if (f->version > 1) { + if (length < 20) + return AVERROR_INVALIDDATA; extra = 20; if (length < extra) return -1; @@ -459,7 +487,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) for (y = 0; y < height; y += 8) { for (x = 0; x < width; x += 8) - decode_p_block(f, dst + x, src + x, 3, 3, stride); + if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0) + return ret; src += 8 * stride; dst += 8 * stride; } @@ -579,7 +608,8 @@ static int decode_i_mb(FourXContext *f) } static const uint8_t *read_huffman_tables(FourXContext *f, - const uint8_t * const buf, int buf_size) + const uint8_t * const buf, + int buf_size) { int frequency[512] = { 0 }; uint8_t flag[512]; @@ -598,8 +628,11 @@ static const uint8_t *read_huffman_tables(FourXContext *f, for (;;) { int i; - if (start <= end && ptr_end - ptr < end - start + 1 + 1) + if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) { + av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n"); return NULL; + } + for (i = start; i <= end; i++) frequency[i] = *ptr++; start = *ptr++; @@ -701,9 +734,9 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length) color[1] = bytestream2_get_le16u(&g3); if (color[0] & 0x8000) - av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); + av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); if (color[1] & 0x8000) - av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + 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]); @@ -732,7 +765,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; } @@ -741,16 +777,17 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) prestream = buf + bitstream_size + 12; if (prestream_size + bitstream_size + 12 != length - || bitstream_size > (1 << 26) || 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; + } init_get_bits(&f->gb, buf + 4, 8 * bitstream_size); @@ -793,30 +830,38 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVFrame *p, temp; int i, frame_4cc, frame_size; - if (buf_size < 12) + if (buf_size < 20) return AVERROR_INVALIDDATA; - frame_4cc = AV_RL32(buf); - if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20) + + av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0); + + 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)); + return AVERROR_INVALIDDATA; + } + + frame_4cc = AV_RL32(buf); if (frame_4cc == AV_RL32("cfrm")) { int free_index = -1; + int id, whole_size; const int data_size = buf_size - 20; - const int id = AV_RL32(buf + 12); - const int whole_size = AV_RL32(buf + 16); CFrameBuffer *cfrm; - if (data_size < 0 || whole_size < 0) { - av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); - return AVERROR_INVALIDDATA; - } - if (f->version <= 1) { av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version); return AVERROR_INVALIDDATA; } + 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; i < CFRAME_BUFFER_COUNT; i++) if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number) av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", @@ -857,6 +902,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, 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 @@ -895,16 +943,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, return -1; } } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) { - if (!f->last_picture.data[0]) { - f->last_picture.reference = 3; - if (ff_get_buffer(avctx, &f->last_picture) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - for (i=0; iheight; i++) - memset(f->last_picture.data[0] + i*f->last_picture.linesize[0], 0, 2*avctx->width); - } - p->pict_type = AV_PICTURE_TYPE_P; if (decode_p_frame(f, buf, frame_size) < 0) { av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n"); diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index cfeedb108e..bfbb63c178 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -64,7 +64,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, 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; @@ -79,6 +79,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, return -1; } + ep = encoded + buf_size; + /* Set data pointer after line lengths */ dp = encoded + planes * (height << 1); @@ -90,19 +92,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, 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(lp - encoded + row*2 + 1 >= buf_size) - return -1; + 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) + 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) + if (ep - dp < count) return -1; while (count--) { *pixptr = *dp++; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 149f61f2c8..4bf3ee1701 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -25,7 +25,6 @@ OBJS = allcodecs.o \ fmtconvert.o \ imgconvert.o \ jrevdct.o \ - log2_tab.o \ mathtables.o \ options.o \ parser.o \ @@ -39,6 +38,7 @@ OBJS = allcodecs.o \ # parts needed for many different codecs OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o OBJS-$(CONFIG_AC3DSP) += ac3dsp.o +OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o OBJS-$(CONFIG_CRYSTALHD) += crystalhd.o OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o OBJS-$(CONFIG_DWT) += dwt.o snow.o @@ -68,6 +68,7 @@ OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ OBJS-$(CONFIG_RANGECODER) += rangecoder.o RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o OBJS-$(CONFIG_RDFT) += rdft.o $(RDFT-OBJS-yes) +OBJS-$(CONFIG_SHARED) += log2_tab.o OBJS-$(CONFIG_SINEWIN) += sinewin.o OBJS-$(CONFIG_VAAPI) += vaapi.o OBJS-$(CONFIG_VDPAU) += vdpau.o @@ -84,8 +85,7 @@ OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps.o \ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \ aacpsy.o aactab.o \ psymodel.o iirfilter.o \ - mpeg4audio.o kbdwin.o \ - audio_frame_queue.o + mpeg4audio.o kbdwin.o OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o kbdwin.o OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \ @@ -317,8 +317,7 @@ OBJS-$(CONFIG_MVC1_DECODER) += mvcdec.o OBJS-$(CONFIG_MVC2_DECODER) += mvcdec.o OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o mjpegdec.o mjpeg.o OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o -OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o \ - audio_frame_queue.o +OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += paf.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += paf.o @@ -358,8 +357,7 @@ OBJS-$(CONFIG_R10K_ENCODER) += r210enc.o OBJS-$(CONFIG_R210_DECODER) += r210dec.o OBJS-$(CONFIG_R210_ENCODER) += r210enc.o OBJS-$(CONFIG_RA_144_DECODER) += ra144dec.o ra144.o celp_filters.o -OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o \ - audio_frame_queue.o +OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_filters.o OBJS-$(CONFIG_RALF_DECODER) += ralf.o OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o @@ -660,43 +658,39 @@ OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o # external codec libraries OBJS-$(CONFIG_LIBAACPLUS_ENCODER) += libaacplus.o OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o -OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o audio_frame_queue.o -OBJS-$(CONFIG_LIBFDK_AAC_ENCODER) += libfdk-aacenc.o audio_frame_queue.o +OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o +OBJS-$(CONFIG_LIBFDK_AAC_ENCODER) += libfdk-aacenc.o OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsm.o OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o -OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o \ - audio_frame_queue.o -OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o \ - audio_frame_queue.o -OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o \ - audio_frame_queue.o +OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o +OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o +OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpegdec.o OBJS-$(CONFIG_LIBOPENJPEG_ENCODER) += libopenjpegenc.o OBJS-$(CONFIG_LIBOPUS_DECODER) += libopusdec.o libopus.o \ vorbis_data.o OBJS-$(CONFIG_LIBOPUS_ENCODER) += libopusenc.o libopus.o \ - vorbis_data.o audio_frame_queue.o + vorbis_data.o OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ libschroedinger.o OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ libschroedinger.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o -OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o audio_frame_queue.o +OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o OBJS-$(CONFIG_LIBUTVIDEO_DECODER) += libutvideodec.o OBJS-$(CONFIG_LIBUTVIDEO_ENCODER) += libutvideoenc.o -OBJS-$(CONFIG_LIBVO_AACENC_ENCODER) += libvo-aacenc.o mpeg4audio.o \ - audio_frame_queue.o +OBJS-$(CONFIG_LIBVO_AACENC_ENCODER) += libvo-aacenc.o mpeg4audio.o OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o -OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o audio_frame_queue.o \ +OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ vorbis_data.o vorbis_parser.o xiph.o OBJS-$(CONFIG_LIBVPX_DECODER) += libvpxdec.o OBJS-$(CONFIG_LIBVPX_ENCODER) += libvpxenc.o diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 0f6cc7636a..84a828f9f0 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -57,9 +57,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 ca49d2fc2a..c2506a5bfd 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 ab6ca4e268..cb93ba9482 100644 --- a/libavcodec/aac_parser.c +++ b/libavcodec/aac_parser.c @@ -34,7 +34,7 @@ static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, int size; union { uint64_t u64; - uint8_t u8[8]; + uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE]; } tmp; tmp.u64 = av_be2ne64(state); diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 994de286c9..45fbc2dedf 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -710,7 +710,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] = { 0 }, uplims[128]; float maxvals[128]; int fflag, minscaler; diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 239153a9f9..56f73ae5d7 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -113,6 +113,10 @@ static VLC vlc_scalefactors; static VLC vlc_spectral[11]; +static int output_configure(AACContext *ac, + uint8_t layout_map[MAX_ELEM_ID*4][3], int tags, + enum OCStatus oc_type, int get_new_frame); + #define overread_err "Input buffer exhausted before END element found\n" static int count_channels(uint8_t (*layout)[3], int tags) @@ -143,6 +147,8 @@ static av_cold int che_configure(AACContext *ac, enum ChannelPosition che_pos, int type, int id, int *channels) { + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; if (che_pos) { if (!ac->che[type][id]) { if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) @@ -184,6 +190,9 @@ static int frame_configure_elements(AVCodecContext *avctx) } } + if (!avctx->channels) + return 1; + /* get output buffer */ ac->frame.nb_samples = 2048; if ((ret = ff_get_buffer(avctx, &ac->frame)) < 0) { @@ -209,28 +218,39 @@ struct elem_to_channel { static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID], uint8_t (*layout_map)[3], int offset, uint64_t left, - uint64_t right, int pos) + uint64_t right, int pos) { if (layout_map[offset][0] == TYPE_CPE) { e2c_vec[offset] = (struct elem_to_channel) { - .av_position = left | right, .syn_ele = TYPE_CPE, - .elem_id = layout_map[offset ][1], .aac_position = pos }; + .av_position = left | right, + .syn_ele = TYPE_CPE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; return 1; } else { - e2c_vec[offset] = (struct elem_to_channel) { - .av_position = left, .syn_ele = TYPE_SCE, - .elem_id = layout_map[offset ][1], .aac_position = pos }; + e2c_vec[offset] = (struct elem_to_channel) { + .av_position = left, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; e2c_vec[offset + 1] = (struct elem_to_channel) { - .av_position = right, .syn_ele = TYPE_SCE, - .elem_id = layout_map[offset + 1][1], .aac_position = pos }; + .av_position = right, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset + 1][1], + .aac_position = pos + }; return 2; } } -static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, int *current) { +static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, + int *current) +{ int num_pos_channels = 0; - int first_cpe = 0; - int sce_parity = 0; + int first_cpe = 0; + int sce_parity = 0; int i; for (i = *current; i < tags; i++) { if (layout_map[i][2] != pos) @@ -244,7 +264,7 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, in } } num_pos_channels += 2; - first_cpe = 1; + first_cpe = 1; } else { num_pos_channels++; sce_parity ^= 1; @@ -252,7 +272,7 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, in } if (sce_parity && ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE)) - return -1; + return -1; *current = i; return num_pos_channels; } @@ -260,7 +280,7 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, in static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) { int i, n, total_non_cc_elements; - struct elem_to_channel e2c_vec[4*MAX_ELEM_ID] = {{ 0 }}; + struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } }; int num_front_channels, num_side_channels, num_back_channels; uint64_t layout; @@ -284,8 +304,11 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) i = 0; if (num_front_channels & 1) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = AV_CH_FRONT_CENTER, .syn_ele = TYPE_SCE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_FRONT }; + .av_position = AV_CH_FRONT_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_FRONT + }; i++; num_front_channels--; } @@ -342,22 +365,31 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) } if (num_back_channels) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = AV_CH_BACK_CENTER, .syn_ele = TYPE_SCE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_BACK }; + .av_position = AV_CH_BACK_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_BACK + }; i++; num_back_channels--; } if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = AV_CH_LOW_FREQUENCY, .syn_ele = TYPE_LFE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE }; + .av_position = AV_CH_LOW_FREQUENCY, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; i++; } while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = UINT64_MAX, .syn_ele = TYPE_LFE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE }; + .av_position = UINT64_MAX, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; i++; } @@ -365,12 +397,11 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) total_non_cc_elements = n = i; do { int next_n = 0; - for (i = 1; i < n; i++) { - if (e2c_vec[i-1].av_position > e2c_vec[i].av_position) { - FFSWAP(struct elem_to_channel, e2c_vec[i-1], e2c_vec[i]); + for (i = 1; i < n; i++) + if (e2c_vec[i - 1].av_position > e2c_vec[i].av_position) { + FFSWAP(struct elem_to_channel, e2c_vec[i - 1], e2c_vec[i]); next_n = i; } - } n = next_n; } while (n > 0); @@ -406,16 +437,19 @@ static void pop_output_configuration(AACContext *ac) { ac->oc[1] = ac->oc[0]; ac->avctx->channels = ac->oc[1].channels; ac->avctx->channel_layout = ac->oc[1].channel_layout; + output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, + ac->oc[1].status, 0); } } /** - * Configure output channel order based on the current program configuration element. + * Configure output channel order based on the current program + * configuration element. * * @return Returns error status. 0 - OK, !0 - error */ static int output_configure(AACContext *ac, - uint8_t layout_map[MAX_ELEM_ID*4][3], int tags, + uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags, enum OCStatus oc_type, int get_new_frame) { AVCodecContext *avctx = ac->avctx; @@ -487,36 +521,40 @@ static void flush(AVCodecContext *avctx) * @return Returns error status. 0 - OK, !0 - error */ static int set_default_channel_config(AVCodecContext *avctx, - uint8_t (*layout_map)[3], - int *tags, - int channel_config) + uint8_t (*layout_map)[3], + int *tags, + int channel_config) { if (channel_config < 1 || channel_config > 7) { - av_log(avctx, AV_LOG_ERROR, "invalid default channel configuration (%d)\n", + av_log(avctx, AV_LOG_ERROR, + "invalid default channel configuration (%d)\n", channel_config); - return -1; + return AVERROR_INVALIDDATA; } *tags = tags_per_config[channel_config]; - memcpy(layout_map, aac_channel_layout_map[channel_config-1], *tags * sizeof(*layout_map)); + memcpy(layout_map, aac_channel_layout_map[channel_config - 1], + *tags * sizeof(*layout_map)); return 0; } static ChannelElement *get_che(AACContext *ac, int type, int elem_id) { - // For PCE based channel configurations map the channels solely based on tags. + /* For PCE based channel configurations map the channels solely based + * on tags. */ if (!ac->oc[1].m4ac.chan_config) { return ac->tag_che_map[type][elem_id]; } // Allow single CPE stereo files to be signalled with mono configuration. - if (!ac->tags_mapped && type == TYPE_CPE && ac->oc[1].m4ac.chan_config == 1) { + if (!ac->tags_mapped && type == TYPE_CPE && + ac->oc[1].m4ac.chan_config == 1) { uint8_t layout_map[MAX_ELEM_ID*4][3]; int layout_map_tags; push_output_configuration(ac); av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n"); - if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags, - 2) < 0) + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 2) < 0) return NULL; if (output_configure(ac, layout_map, layout_map_tags, OC_TRIAL_FRAME, 1) < 0) @@ -526,15 +564,16 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) ac->oc[1].m4ac.ps = 0; } // And vice-versa - if (!ac->tags_mapped && type == TYPE_SCE && ac->oc[1].m4ac.chan_config == 2) { - uint8_t layout_map[MAX_ELEM_ID*4][3]; + if (!ac->tags_mapped && type == TYPE_SCE && + ac->oc[1].m4ac.chan_config == 2) { + uint8_t layout_map[MAX_ELEM_ID * 4][3]; int layout_map_tags; push_output_configuration(ac); av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n"); - if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags, - 1) < 0) + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 1) < 0) return NULL; if (output_configure(ac, layout_map, layout_map_tags, OC_TRIAL_FRAME, 1) < 0) @@ -544,7 +583,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) if (ac->oc[1].m4ac.sbr) ac->oc[1].m4ac.ps = -1; } - // For indexed channel configurations map the channels solely based on position. + /* For indexed channel configurations map the channels solely based + * on position. */ switch (ac->oc[1].m4ac.chan_config) { case 7: if (ac->tags_mapped == 3 && type == TYPE_CPE) { @@ -552,9 +592,12 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; } case 6: - /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1] - instead of SCE[0] CPE[0] CPE[1] LFE[0]. If we seem to have - encountered such a stream, transfer the LFE[0] element to the SCE[1]'s mapping */ + /* Some streams incorrectly code 5.1 audio as + * SCE[0] CPE[0] CPE[1] SCE[1] + * instead of + * SCE[0] CPE[0] CPE[1] LFE[0]. + * If we seem to have encountered such a stream, transfer + * the LFE[0] element to the SCE[1]'s mapping */ if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) { ac->tags_mapped++; return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0]; @@ -565,13 +608,16 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1]; } case 4: - if (ac->tags_mapped == 2 && ac->oc[1].m4ac.chan_config == 4 && type == TYPE_SCE) { + if (ac->tags_mapped == 2 && + ac->oc[1].m4ac.chan_config == 4 && + type == TYPE_SCE) { ac->tags_mapped++; return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1]; } case 3: case 2: - if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && type == TYPE_CPE) { + if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && + type == TYPE_CPE) { ac->tags_mapped++; return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0]; } else if (ac->oc[1].m4ac.chan_config == 2) { @@ -588,7 +634,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) } /** - * Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit. + * Decode an array of 4 bit element IDs, optionally interleaved with a + * stereo/mono switching bit. * * @param type speaker type/position for these channels */ @@ -630,7 +677,8 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, uint8_t (*layout_map)[3], GetBitContext *gb) { - int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc, sampling_index; + int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc; + int sampling_index; int comment_len; int tags; @@ -638,7 +686,9 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, sampling_index = get_bits(gb, 4); if (m4ac->sampling_index != sampling_index) - av_log(avctx, AV_LOG_WARNING, "Sample rate index in program config element does not match the sample rate index configured by the container.\n"); + av_log(avctx, AV_LOG_WARNING, + "Sample rate index in program config element does not " + "match the sample rate index configured by the container.\n"); num_front = get_bits(gb, 4); num_side = get_bits(gb, 4); @@ -679,7 +729,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, "decode_pce: " overread_err); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(gb, comment_len); return tags; @@ -721,7 +771,8 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, if (tags < 0) return tags; } else { - if ((ret = set_default_channel_config(avctx, layout_map, &tags, channel_config))) + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) return ret; } @@ -743,7 +794,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, case AOT_ER_AAC_LTP: case AOT_ER_AAC_SCALABLE: case AOT_ER_AAC_LD: - skip_bits(gb, 3); /* aacSectionDataResilienceFlag + skip_bits(gb, 3); /* aacSectionDataResilienceFlag * aacScalefactorDataResilienceFlag * aacSpectralDataResilienceFlag */ @@ -773,20 +824,24 @@ static int decode_audio_specific_config(AACContext *ac, int sync_extension) { GetBitContext gb; - int i; + int i, ret; av_dlog(avctx, "audio specific config size %d\n", bit_size >> 3); for (i = 0; i < bit_size >> 3; i++) av_dlog(avctx, "%02x ", data[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; + if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, + sync_extension)) < 0) + 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; + av_log(avctx, AV_LOG_ERROR, + "invalid sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; } skip_bits_long(&gb, i); @@ -795,18 +850,23 @@ 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; + av_log(avctx, AV_LOG_ERROR, + "Audio object type %s%d is not supported.\n", + m4ac->sbr == 1 ? "SBR+" : "", + m4ac->object_type); + return AVERROR(ENOSYS); } - av_dlog(avctx, "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", + av_dlog(avctx, + "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", m4ac->object_type, m4ac->chan_config, m4ac->sampling_index, - m4ac->sample_rate, m4ac->sbr, m4ac->ps); + m4ac->sample_rate, m4ac->sbr, + m4ac->ps); return get_bits_count(&gb); } @@ -864,15 +924,18 @@ static void reset_predictor_group(PredictorState *ps, int group_num) reset_predict_state(&ps[i]); } -#define AAC_INIT_VLC_STATIC(num, size) \ - INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ - ff_aac_spectral_bits[num], sizeof( ff_aac_spectral_bits[num][0]), sizeof( ff_aac_spectral_bits[num][0]), \ - ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), sizeof(ff_aac_spectral_codes[num][0]), \ +#define AAC_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ + ff_aac_spectral_bits[num], sizeof(ff_aac_spectral_bits[num][0]), \ + sizeof(ff_aac_spectral_bits[num][0]), \ + ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), \ + sizeof(ff_aac_spectral_codes[num][0]), \ size); static av_cold int aac_decode_init(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; + int ret; ac->avctx = avctx; ac->oc[1].m4ac.sample_rate = avctx->sample_rate; @@ -880,10 +943,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (avctx->extradata_size > 0) { - if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, - avctx->extradata, - avctx->extradata_size*8, 1) < 0) - return -1; + if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + avctx->extradata, + avctx->extradata_size * 8, + 1)) < 0) + return ret; } else { int sr, i; uint8_t layout_map[MAX_ELEM_ID*4][3]; @@ -914,6 +978,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) } } + if (avctx->channels > MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } + AAC_INIT_VLC_STATIC( 0, 304); AAC_INIT_VLC_STATIC( 1, 270); AAC_INIT_VLC_STATIC( 2, 550); @@ -936,9 +1005,14 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) ff_aac_tableinit(); - INIT_VLC_STATIC(&vlc_scalefactors,7,FF_ARRAY_ELEMS(ff_aac_scalefactor_code), - ff_aac_scalefactor_bits, sizeof(ff_aac_scalefactor_bits[0]), sizeof(ff_aac_scalefactor_bits[0]), - ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]), + INIT_VLC_STATIC(&vlc_scalefactors, 7, + FF_ARRAY_ELEMS(ff_aac_scalefactor_code), + ff_aac_scalefactor_bits, + sizeof(ff_aac_scalefactor_bits[0]), + sizeof(ff_aac_scalefactor_bits[0]), + ff_aac_scalefactor_code, + sizeof(ff_aac_scalefactor_code[0]), + sizeof(ff_aac_scalefactor_code[0]), 352); ff_mdct_init(&ac->mdct, 11, 1, 1.0 / (32768.0 * 1024.0)); @@ -972,7 +1046,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, "skip_data_stream_element: "overread_err); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(gb, 8 * count); return 0; @@ -984,9 +1058,11 @@ static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, int sfb; if (get_bits1(gb)) { 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; + if (ics->predictor_reset_group == 0 || + ics->predictor_reset_group > 30) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid Predictor Reset Group.\n"); + return AVERROR_INVALIDDATA; } } for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) { @@ -1055,7 +1131,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, goto fail; } } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) { - av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n"); + av_log(ac->avctx, AV_LOG_ERROR, + "Prediction is not allowed in AAC-LC.\n"); goto fail; } else { if ((ics->ltp.present = get_bits(gb, 1))) @@ -1066,7 +1143,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, if (ics->max_sfb > ics->num_swb) { av_log(ac->avctx, AV_LOG_ERROR, - "Number of scalefactor bands in group (%d) exceeds limit (%d).\n", + "Number of scalefactor bands in group (%d) " + "exceeds limit (%d).\n", ics->max_sfb, ics->num_swb); goto fail; } @@ -1099,20 +1177,20 @@ 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; } do { sect_len_incr = get_bits(gb, bits); sect_end += sect_len_incr; if (get_bits_left(gb) < 0) { av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err); - return -1; + 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 -1; + return AVERROR_INVALIDDATA; } } while (sect_len_incr == (1 << bits) - 1); for (; k < sect_end; k++) { @@ -1150,7 +1228,8 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, if (band_type[idx] == ZERO_BT) { for (; i < run_end; i++, idx++) sf[idx] = 0.; - } else if ((band_type[idx] == INTENSITY_BT) || (band_type[idx] == INTENSITY_BT2)) { + } else if ((band_type[idx] == INTENSITY_BT) || + (band_type[idx] == INTENSITY_BT2)) { for (; i < run_end; i++, idx++) { offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; clipped_offset = av_clip(offset[2], -155, 100); @@ -1183,7 +1262,7 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, if (offset[0] > 255U) { av_log(ac->avctx, AV_LOG_ERROR, "Scalefactor (%d) out of range.\n", offset[0]); - return -1; + return AVERROR_INVALIDDATA; } sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO]; } @@ -1238,10 +1317,11 @@ static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns, tns->length[w][filt] = get_bits(gb, 6 - 2 * is8); if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) { - av_log(ac->avctx, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.\n", + 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); @@ -1270,7 +1350,9 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb, { int idx; if (ms_present == 1) { - for (idx = 0; idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; idx++) + for (idx = 0; + idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; + idx++) cpe->ms_mask[idx] = get_bits1(gb); } else if (ms_present == 2) { memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask[0]) * cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb); @@ -1369,7 +1451,8 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], float *coef_base = coef; for (g = 0; g < ics->num_windows; g++) - memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb])); + memset(coef + g * 128 + offsets[ics->max_sfb], 0, + sizeof(float) * (c - offsets[ics->max_sfb])); for (g = 0; g < ics->num_window_groups; g++) { unsigned g_len = ics->group_len[g]; @@ -1524,7 +1607,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); @@ -1639,14 +1722,20 @@ static void apply_prediction(AACContext *ac, SingleChannelElement *sce) } if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { - for (sfb = 0; sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; sfb++) { - for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) { + for (sfb = 0; + sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; + sfb++) { + for (k = sce->ics.swb_offset[sfb]; + k < sce->ics.swb_offset[sfb + 1]; + k++) { predict(&sce->predictor_state[k], &sce->coeffs[k], - sce->ics.predictor_present && sce->ics.prediction_used[sfb]); + sce->ics.predictor_present && + sce->ics.prediction_used[sfb]); } } if (sce->ics.predictor_reset_group) - reset_predictor_group(sce->predictor_state, sce->ics.predictor_reset_group); + reset_predictor_group(sce->predictor_state, + sce->ics.predictor_reset_group); } else reset_all_predictors(sce->predictor_state); } @@ -1667,6 +1756,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. @@ -1680,33 +1770,38 @@ 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; + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse tool not allowed in eight short sequence.\n"); + 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; + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse data corrupt or invalid.\n"); + 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 AVERROR_PATCHWELCOME; } } - if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, &pulse, ics, sce->band_type) < 0) - return -1; + if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, + &pulse, ics, sce->band_type) < 0) + return AVERROR_INVALIDDATA; if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window) apply_prediction(ac, sce); @@ -1727,7 +1822,8 @@ static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) for (g = 0; g < ics->num_window_groups; g++) { for (i = 0; i < ics->max_sfb; i++, idx++) { if (cpe->ms_mask[idx] && - cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) { + cpe->ch[0].band_type[idx] < NOISE_BT && + cpe->ch[1].band_type[idx] < NOISE_BT) { for (group = 0; group < ics->group_len[g]; group++) { ac->dsp.butterflies_float(ch0 + group * 128 + offsets[i], ch1 + group * 128 + offsets[i], @@ -1747,7 +1843,8 @@ static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) * [1] mask is decoded from bitstream; [2] mask is all 1s; * [3] reserved for scalable AAC */ -static void apply_intensity_stereo(AACContext *ac, ChannelElement *cpe, int ms_present) +static void apply_intensity_stereo(AACContext *ac, + ChannelElement *cpe, int ms_present) { const IndividualChannelStream *ics = &cpe->ch[1].ics; SingleChannelElement *sce1 = &cpe->ch[1]; @@ -1758,7 +1855,8 @@ static void apply_intensity_stereo(AACContext *ac, ChannelElement *cpe, int ms_p float scale; for (g = 0; g < ics->num_window_groups; g++) { for (i = 0; i < ics->max_sfb;) { - if (sce1->band_type[idx] == INTENSITY_BT || sce1->band_type[idx] == INTENSITY_BT2) { + if (sce1->band_type[idx] == INTENSITY_BT || + sce1->band_type[idx] == INTENSITY_BT2) { const int bt_run_end = sce1->band_type_run_end[idx]; for (; i < bt_run_end; i++, idx++) { c = -1 + 2 * (sce1->band_type[idx] - 14); @@ -1798,13 +1896,14 @@ static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) i = cpe->ch[1].ics.use_kb_window[0]; cpe->ch[1].ics = cpe->ch[0].ics; cpe->ch[1].ics.use_kb_window[1] = i; - if (cpe->ch[1].ics.predictor_present && (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN)) + if (cpe->ch[1].ics.predictor_present && + (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN)) if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1))) decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb); 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); } @@ -2665,7 +2764,8 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, if (ac->force_dmono_mode >= 0) ac->dmono_mode = ac->force_dmono_mode; - 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, avpkt)) < 0) return err; @@ -2701,13 +2801,13 @@ static av_cold int aac_decode_close(AVCodecContext *avctx) #define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word struct LATMContext { - AACContext aac_ctx; ///< containing AACContext - int initialized; ///< initialized after a valid extradata was seen + AACContext aac_ctx; ///< containing AACContext + int initialized; ///< initilized after a valid extradata was seen // parser data - int audio_mux_version_A; ///< LATM syntax version - int frame_length_type; ///< 0/1 variable/fixed frame length - int frame_length; ///< frame length for fixed frame length + int audio_mux_version_A; ///< LATM syntax version + int frame_length_type; ///< 0/1 variable/fixed frame length + int frame_length; ///< frame length for fixed frame length }; static inline uint32_t latm_get_value(GetBitContext *b) @@ -2915,7 +3015,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 2c40ec91f5..4dcd60459e 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -166,7 +166,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); @@ -517,7 +517,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* add current frame to queue */ if (frame) { - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 714e48c1ff..a49631b9b5 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -1121,7 +1121,12 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { float temp1 = exp2f(sbr->data[0].env_facs[e][k] * alpha + 7.0f); float temp2 = exp2f((pan_offset - sbr->data[1].env_facs[e][k]) * alpha); - float fac = temp1 / (1.0f + temp2); + float fac; + if (temp1 > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = 1; + } + fac = temp1 / (1.0f + temp2); sbr->data[0].env_facs[e][k] = fac; sbr->data[1].env_facs[e][k] = fac * temp2; } @@ -1130,7 +1135,12 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) for (k = 0; k < sbr->n_q; k++) { float temp1 = exp2f(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs[e][k] + 1); float temp2 = exp2f(12 - sbr->data[1].noise_facs[e][k]); - float fac = temp1 / (1.0f + temp2); + float fac; + if (temp1 > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = 1; + } + fac = temp1 / (1.0f + temp2); sbr->data[0].noise_facs[e][k] = fac; sbr->data[1].noise_facs[e][k] = fac * temp2; } @@ -1139,9 +1149,15 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { float alpha = sbr->data[ch].bs_amp_res ? 1.0f : 0.5f; for (e = 1; e <= sbr->data[ch].bs_num_env; e++) - for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++) + for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ sbr->data[ch].env_facs[e][k] = exp2f(alpha * sbr->data[ch].env_facs[e][k] + 6.0f); + if (sbr->data[ch].env_facs[e][k] > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + sbr->data[ch].env_facs[e][k] = 1; + } + } + for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) for (k = 0; k < sbr->n_q; k++) sbr->data[ch].noise_facs[e][k] = diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index 0d4704fc3e..245951ab16 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -60,7 +60,7 @@ static av_cold int aasc_decode_init(AVCodecContext *avctx) } break; case 16: - avctx->pix_fmt = AV_PIX_FMT_RGB555; + avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break; case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 8dc4c0d480..acfbc2ea66 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -147,7 +147,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, int err; union { uint64_t u64; - uint8_t u8[8]; + uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE]; } tmp = { av_be2ne64(state) }; AC3HeaderInfo hdr; GetBitContext gbc; diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 567c797659..efec001c01 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -292,7 +292,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); } } @@ -787,12 +787,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; @@ -869,7 +869,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 */ @@ -899,7 +899,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; @@ -921,7 +921,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]; } @@ -951,7 +951,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 */ @@ -1006,7 +1006,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; } @@ -1029,7 +1029,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 */ @@ -1049,7 +1049,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; } } @@ -1080,7 +1080,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; } } @@ -1119,7 +1119,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; } @@ -1131,7 +1131,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); } @@ -1172,7 +1172,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) { @@ -1291,7 +1291,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; @@ -1305,17 +1305,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 */ @@ -1336,8 +1339,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) @@ -1360,22 +1365,18 @@ 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; - } - if (avctx->channels != s->out_channels) { - av_log(avctx, AV_LOG_ERROR, "channel number mismatching on damaged frame\n"); + } 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) avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; /* get output buffer */ - avctx->channels = s->out_channels; s->frame.nb_samples = s->num_blocks * 256; if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 904e0bb9ef..5b06531b56 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -259,7 +259,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) energy_cpl = energy[blk][CPL_CH][bnd]; energy_ch = energy[blk][ch][bnd]; blk1 = blk+1; - while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) { + while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) { if (s->blocks[blk1].cpl_in_use) { energy_cpl += energy[blk1][CPL_CH][bnd]; energy_ch += energy[blk1][ch][bnd]; diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index cd68257256..40ead437f8 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -1387,7 +1387,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, static const enum AVSampleFormat sample_fmts_s16[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; -static const enum AVSampleFormat sample_fmts_s16p[] = { AV_SAMPLE_FMT_S16, +static const enum AVSampleFormat sample_fmts_s16p[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }; static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index 217d165f30..c2bc963a5c 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -550,7 +550,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, case AV_CODEC_ID_ADPCM_IMA_QT: { PutBitContext pb; - init_put_bits(&pb, dst, pkt_size * 8); + init_put_bits(&pb, dst, pkt_size); for (ch = 0; ch < avctx->channels; ch++) { ADPCMChannelStatus *status = &c->status[ch]; @@ -558,10 +558,11 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, put_bits(&pb, 7, status->step_index); if (avctx->trellis > 0) { uint8_t buf[64]; - adpcm_compress_trellis(avctx, &samples_p[ch][1], buf, status, + adpcm_compress_trellis(avctx, &samples_p[ch][0], buf, status, 64, 1); for (i = 0; i < 64; i++) put_bits(&pb, 4, buf[i ^ 1]); + status->prev_sample = status->predictor; } else { for (i = 0; i < 64; i += 2) { int t1, t2; @@ -579,7 +580,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, case AV_CODEC_ID_ADPCM_SWF: { PutBitContext pb; - init_put_bits(&pb, dst, pkt_size * 8); + init_put_bits(&pb, dst, pkt_size); n = frame->nb_samples - 1; diff --git a/libavcodec/adx.c b/libavcodec/adx.c index 7da696d0a8..9b58e378c2 100644 --- a/libavcodec/adx.c +++ b/libavcodec/adx.c @@ -47,13 +47,8 @@ int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, return AVERROR_INVALIDDATA; offset = AV_RB16(buf + 2) + 4; - if (offset < 6) { - av_log(avctx, AV_LOG_ERROR, "offset is prior data\n"); - return AVERROR_INVALIDDATA; - } - /* 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/alac.c b/libavcodec/alac.c index 180ef53105..48b0b991cf 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -321,6 +321,9 @@ static int decode_element(AVCodecContext *avctx, void *data, int ch_index, rice_history_mult[ch] = get_bits(&alac->gb, 3); lpc_order[ch] = get_bits(&alac->gb, 5); + if (lpc_order[ch] >= alac->max_samples_per_frame) + return AVERROR_INVALIDDATA; + /* read the predictor table */ for (i = lpc_order[ch] - 1; i >= 0; i--) lpc_coefs[ch][i] = get_sbits(&alac->gb, 16); @@ -462,9 +465,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, } channels = (element == TYPE_CPE) ? 2 : 1; - if ( ch + channels > alac->channels - || ff_alac_channel_layout_offsets[alac->channels - 1][ch] + channels > alac->channels - ) { + if (ch + channels > alac->channels || + ff_alac_channel_layout_offsets[alac->channels - 1][ch] + channels > alac->channels) { av_log(avctx, AV_LOG_ERROR, "invalid element channel count\n"); return AVERROR_INVALIDDATA; } @@ -546,7 +548,8 @@ static int alac_set_info(ALACContext *alac) bytestream2_skipu(&gb, 12); // size:4, alac:4, version:4 alac->max_samples_per_frame = bytestream2_get_be32u(&gb); - if (!alac->max_samples_per_frame || alac->max_samples_per_frame > INT_MAX) { + if (!alac->max_samples_per_frame || + alac->max_samples_per_frame > INT_MAX / sizeof(int32_t)) { av_log(alac->avctx, AV_LOG_ERROR, "max samples per frame invalid: %u\n", alac->max_samples_per_frame); return AVERROR_INVALIDDATA; diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index 71e2a74822..56cbfdcedb 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -67,7 +67,7 @@ typedef struct AlacEncodeContext { int write_sample_size; int extra_bits; int32_t sample_buf[2][DEFAULT_FRAME_SIZE]; - int32_t predictor_buf[DEFAULT_FRAME_SIZE]; + int32_t predictor_buf[2][DEFAULT_FRAME_SIZE]; int interlacing_shift; int interlacing_leftweight; PutBitContext pbctx; @@ -254,13 +254,14 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) { int i; AlacLPCContext lpc = s->lpc[ch]; + int32_t *residual = s->predictor_buf[ch]; if (lpc.lpc_order == 31) { - s->predictor_buf[0] = s->sample_buf[ch][0]; + residual[0] = s->sample_buf[ch][0]; for (i = 1; i < s->frame_size; i++) { - s->predictor_buf[i] = s->sample_buf[ch][i ] - - s->sample_buf[ch][i - 1]; + residual[i] = s->sample_buf[ch][i ] - + s->sample_buf[ch][i - 1]; } return; @@ -270,12 +271,11 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) if (lpc.lpc_order > 0) { int32_t *samples = s->sample_buf[ch]; - int32_t *residual = s->predictor_buf; // 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->frame_size; i++) { @@ -314,11 +314,11 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) } } -static void alac_entropy_coder(AlacEncodeContext *s) +static void alac_entropy_coder(AlacEncodeContext *s, int ch) { unsigned int history = s->rc.initial_history; int sign_modifier = 0, i, k; - int32_t *samples = s->predictor_buf; + int32_t *samples = s->predictor_buf[ch]; for (i = 0; i < s->frame_size;) { int x; @@ -395,6 +395,19 @@ static void write_element(AlacEncodeContext *s, init_sample_buffers(s, channels, samples); write_element_header(s, element, instance); + // extract extra bits if needed + if (s->extra_bits) { + uint32_t mask = (1 << s->extra_bits) - 1; + for (j = 0; j < channels; j++) { + int32_t *extra = s->predictor_buf[j]; + int32_t *smp = s->sample_buf[j]; + for (i = 0; i < s->frame_size; i++) { + extra[i] = smp[i] & mask; + smp[i] >>= s->extra_bits; + } + } + } + if (channels == 2) alac_stereo_decorrelation(s); else @@ -420,8 +433,7 @@ static void write_element(AlacEncodeContext *s, uint32_t mask = (1 << s->extra_bits) - 1; for (i = 0; i < s->frame_size; i++) { for (j = 0; j < channels; j++) { - put_bits(pb, s->extra_bits, s->sample_buf[j][i] & mask); - s->sample_buf[j][i] >>= s->extra_bits; + put_bits(pb, s->extra_bits, s->predictor_buf[j][i] & mask); } } } @@ -433,10 +445,11 @@ static void write_element(AlacEncodeContext *s, // TODO: determine when this will actually help. for now it's not used. if (prediction_type == 15) { // 2nd pass 1st order filter + int32_t *residual = s->predictor_buf[channels]; for (j = s->frame_size - 1; j > 0; j--) - s->predictor_buf[j] -= s->predictor_buf[j - 1]; + residual[j] -= residual[j - 1]; } - alac_entropy_coder(s); + alac_entropy_coder(s, i); } } } diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index d7baa6eccb..90acf2c8c1 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -285,7 +285,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; @@ -296,12 +296,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); @@ -336,7 +336,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; @@ -351,7 +351,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); @@ -377,7 +377,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); @@ -391,10 +391,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); @@ -402,7 +402,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); @@ -646,7 +646,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; @@ -983,14 +983,13 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) *bd->shift_lsbs = 0; // read block type flag and read the samples accordingly if (get_bits1(gb)) { - if ((ret = read_var_block_data(ctx, bd)) < 0) - return ret; + ret = read_var_block_data(ctx, bd); } else { if ((ret = read_const_block_data(ctx, bd)) < 0) return ret; } - return 0; + return ret; } @@ -999,12 +998,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 @@ -1022,14 +1025,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); } @@ -1055,6 +1054,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 = { 0 }; @@ -1075,10 +1075,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; @@ -1097,6 +1097,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] = { { 0 } }; bd[0].ra_block = ra_frame; @@ -1138,12 +1139,9 @@ 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) { @@ -1169,8 +1167,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. */ @@ -1186,19 +1195,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, 31)]; - current->weighting[1] = mcc_weightings[av_clip(decode_rice(gb, 2) + 14, 0, 31)]; - current->weighting[2] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; + 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, 31)]; - current->weighting[4] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; - current->weighting[5] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; + 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; @@ -1211,7 +1220,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); @@ -1243,7 +1252,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; @@ -1314,8 +1323,8 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) unsigned int div_blocks[32]; ///< block sizes. unsigned int c; 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) @@ -1346,13 +1355,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++; } @@ -1371,7 +1382,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(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels); @@ -1383,6 +1394,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; @@ -1403,11 +1419,12 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) return ret; } - 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; @@ -1612,30 +1629,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; avctx->bits_per_raw_sample = 32; @@ -1670,7 +1687,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 @@ -1695,8 +1713,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++) @@ -1713,8 +1731,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++) @@ -1734,8 +1752,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 @@ -1752,8 +1770,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; } } @@ -1763,6 +1781,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/ansi.c b/libavcodec/ansi.c index e705da6281..f0351aba6b 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -415,7 +415,7 @@ static int decode_frame(AVCodecContext *avctx, switch(buf[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - if (s->nb_args < MAX_NB_ARGS) + if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] < 6553) s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0'; break; case ';': diff --git a/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S index 0c54b52987..a703322ab6 100644 --- a/libavcodec/arm/dsputil_armv6.S +++ b/libavcodec/arm/dsputil_armv6.S @@ -144,10 +144,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 @@ -196,9 +197,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/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c index f150a4508d..3acc2fc3f4 100644 --- a/libavcodec/arm/h264dsp_init_arm.c +++ b/libavcodec/arm/h264dsp_init_arm.c @@ -91,7 +91,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 6b28a97af8..29fdfe0f37 100644 --- a/libavcodec/arm/int_neon.S +++ b/libavcodec/arm/int_neon.S @@ -41,10 +41,10 @@ function ff_scalarproduct_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] @@ -81,10 +81,10 @@ function ff_scalarproduct_and_madd_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] diff --git a/libavcodec/arm/videodsp_armv5te.S b/libavcodec/arm/videodsp_armv5te.S index c3cd459764..48a6c3ba83 100644 --- a/libavcodec/arm/videodsp_armv5te.S +++ b/libavcodec/arm/videodsp_armv5te.S @@ -22,7 +22,6 @@ #include "config.h" #include "libavutil/arm/asm.S" -#if HAVE_ARMV5TE_EXTERNAL function ff_prefetch_arm, export=1 subs r2, r2, #1 pld [r0] @@ -30,4 +29,3 @@ function ff_prefetch_arm, export=1 bne ff_prefetch_arm bx lr endfunc -#endif diff --git a/libavcodec/arm/videodsp_init_armv5te.c b/libavcodec/arm/videodsp_init_armv5te.c index c6ca1146ea..d11a07061b 100644 --- a/libavcodec/arm/videodsp_init_armv5te.c +++ b/libavcodec/arm/videodsp_init_armv5te.c @@ -19,7 +19,7 @@ */ #include "libavutil/arm/cpu.h" -#include +#include "libavcodec/videodsp.h" #include "videodsp_arm.h" void ff_prefetch_arm(uint8_t *mem, ptrdiff_t stride, int h); diff --git a/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S index fd254ccc30..4047aabc13 100644 --- a/libavcodec/arm/vp8dsp_armv6.S +++ b/libavcodec/arm/vp8dsp_armv6.S @@ -124,14 +124,14 @@ function ff_vp8_luma_dc_wht_armv6, export=1 sbfx r1, r9, #3, #13 sbfx r10, r4, #3, #13 #else - sxth r8, r8 - sxth r7, r7 - sxth r9, r9 - sxth r4, r4 - asr r8, #3 @ block[0][0] - asr r7, #3 @ block[0][1] - asr r9, #3 @ block[0][2] - asr r4, #3 @ block[0][3] + sxth r6, r8 + sxth r12, r7 + sxth r1, r9 + sxth r10, r4 + asr r6, #3 @ block[0][0] + asr r12, #3 @ block[0][1] + asr r1, #3 @ block[0][2] + asr r10, #3 @ block[0][3] #endif strh r6, [r0], #32 diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c index 7c3b30c8db..5e70d4b32a 100644 --- a/libavcodec/asvdec.c +++ b/libavcodec/asvdec.c @@ -282,6 +282,11 @@ static av_cold int decode_init(AVCodecContext *avctx) const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; int i; + if (avctx->extradata_size < 1) { + av_log(avctx, AV_LOG_ERROR, "No extradata provided\n"); + return AVERROR_INVALIDDATA; + } + ff_asv_common_init(avctx); init_vlcs(a); ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_asv_scantab); diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 56efa19466..e332ef87bd 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -165,7 +165,10 @@ static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes) off = (intptr_t)input & 3; buf = (const uint32_t *)(input - off); - c = av_be2ne32((0x537F6103 >> (off * 8)) | (0x537F6103 << (32 - (off * 8)))); + 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++) output[i] = c ^ buf[i]; @@ -518,7 +521,7 @@ static int add_tonal_components(float *spectrum, int num_components, output = &spectrum[components[i].pos]; for (j = 0; j < components[i].num_coefs; j++) - output[i] += input[i]; + output[j] += input[j]; } return last_pos; @@ -662,8 +665,8 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, snd->num_components = decode_tonal_components(gb, snd->components, snd->bands_coded); - if (snd->num_components == -1) - return -1; + if (snd->num_components < 0) + return snd->num_components; num_subbands = decode_spectrum(gb, snd->spectrum); @@ -740,7 +743,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* set the bitstream reader at the start of the second Sound Unit*/ - init_get_bits(&q->gb, ptr1, avctx->block_align * 8); + init_get_bits(&q->gb, ptr1, (avctx->block_align - i) * 8); /* Fill the Weighting coeffs delay buffer */ memmove(q->weighting_delay, &q->weighting_delay[2], @@ -949,9 +952,11 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (q->coding_mode == STEREO) av_log(avctx, AV_LOG_DEBUG, "Normal stereo detected.\n"); - else if (q->coding_mode == JOINT_STEREO) + else if (q->coding_mode == JOINT_STEREO) { + if (avctx->channels != 2) + return AVERROR_INVALIDDATA; av_log(avctx, AV_LOG_DEBUG, "Joint stereo detected.\n"); - else { + } else { av_log(avctx, AV_LOG_ERROR, "Unknown channel coding mode %x!\n", q->coding_mode); return AVERROR_INVALIDDATA; diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 516f1c972b..c8724de346 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -283,7 +283,7 @@ int av_packet_split_side_data(AVPacket *pkt){ for (i=0; ; i++){ size= AV_RB32(p); av_assert0(size<=INT_MAX && p - pkt->data >= size); - pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + pkt->side_data[i].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); pkt->side_data[i].size = size; pkt->side_data[i].type = p[4]&127; if (!pkt->side_data[i].data) diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 3e2bb71d85..d90f79548f 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -170,7 +170,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; @@ -181,8 +181,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; } /** @@ -681,6 +685,9 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * } } + if (quant_idx >= 16) + return AVERROR_INVALIDDATA; + quant = quant_matrices[quant_idx]; block[0] = (block[0] * quant[0]) >> 11; @@ -1264,7 +1271,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; @@ -1299,7 +1306,10 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_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/bmv.c b/libavcodec/bmv.c index defa1ab88b..a68b122444 100644 --- a/libavcodec/bmv.c +++ b/libavcodec/bmv.c @@ -140,7 +140,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, 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: diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index af7f75bd45..41d68cffaf 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -325,6 +325,32 @@ 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) diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 385721fe1d..d8f34c8602 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -305,7 +305,7 @@ STOP_TIMER("get_cabac_bypass") for(i=0; igb); - if (cbp > 63U) { - av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp\n"); + + if (cbp > 63 || cbp < 0) { + av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp); return -1; } h->cbp = cbp_tab[cbp][1]; @@ -675,7 +676,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) /* get coded block pattern */ if (h->cur.f->pict_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->avctx, AV_LOG_ERROR, "illegal intra cbp\n"); return -1; } @@ -944,6 +945,11 @@ static int decode_pic(AVSContext *h) int ret; enum cavs_mb mb_type; + if (!h->top_qp) { + av_log(h->avctx, AV_LOG_ERROR, "No sequence header decoded yet\n"); + return AVERROR_INVALIDDATA; + } + skip_bits(&h->gb, 16);//bbv_dwlay if (h->stc == PIC_PB_START_CODE) { h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I; @@ -973,7 +979,8 @@ static int decode_pic(AVSContext *h) if (h->cur.f->data[0]) h->avctx->release_buffer(h->avctx, h->cur.f); - if ((ret = ff_get_buffer(h->avctx, h->cur.f)) < 0) + ret = ff_get_buffer(h->avctx, h->cur.f); + if (ret < 0) return ret; if (!h->edge_emu_buffer) { diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index 71d9da7ee2..54d39db37a 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -269,7 +269,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, static int cdg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; + GetByteContext gb; int buf_size = avpkt->size; int ret; uint8_t command, inst; @@ -286,17 +286,19 @@ static int cdg_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } + bytestream2_init(&gb, avpkt->data, avpkt->size); + ret = avctx->reget_buffer(avctx, &cc->frame); if (ret) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 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) { @@ -355,11 +357,10 @@ static int cdg_decode_frame(AVCodecContext *avctx, *got_frame = 1; } else { *got_frame = 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/dcadec.c b/libavcodec/dcadec.c index e7ae6e2d20..b768a9a304 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -738,10 +738,10 @@ 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 == 3) { + if (s->lfe > 2) { s->lfe = 0; - av_log_ask_for_sample(s->avctx, "LFE is 3\n"); - return AVERROR_PATCHWELCOME; + av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE value: %d\n", s->lfe); + return AVERROR_INVALIDDATA; } /* TODO: check CRC */ @@ -971,7 +971,13 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) "Invalid channel mode %d\n", am); return AVERROR_INVALIDDATA; } - for (j = base_channel; j < FFMIN(s->prim_channels, FF_ARRAY_ELEMS(dca_default_coeffs[am])); j++) { + 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]; } @@ -1425,6 +1431,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; } } diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index b324c6e5ba..08938073b2 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -263,6 +263,8 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height segments = bytestream2_get_le16(gb); } line_ptr = frame; + if (frame_end - frame < width) + return AVERROR_INVALIDDATA; frame += width; y++; while (segments--) { diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index 2dd754f752..e132acc44a 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -237,7 +237,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format]; avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift); - if (!(source->width % (1<height % (1<width % (1<height % (1<range * prob_zero) >> 16; -#if HAVE_FAST_CMOV && HAVE_INLINE_ASM +#if HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS low -= range_times_prob << 16; range -= range_times_prob; bit = 0; diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index c431b97019..fa342cc7e1 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -200,6 +200,7 @@ typedef struct DiracContext { uint16_t *mctmp; /* buffer holding the MC data multipled by OBMC weights */ uint8_t *mcscratch; + int buffer_stride; DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE]; @@ -342,22 +343,44 @@ static int alloc_sequence_buffers(DiracContext *s) return AVERROR(ENOMEM); } - w = s->source.width; - h = s->source.height; - /* fixme: allocate using real stride here */ - s->sbsplit = av_malloc(sbwidth * sbheight); - s->blmotion = av_malloc(sbwidth * sbheight * 16 * sizeof(*s->blmotion)); - s->edge_emu_buffer_base = av_malloc((w+64)*MAX_BLOCKSIZE); + s->sbsplit = av_malloc_array(sbwidth, sbheight); + s->blmotion = av_malloc_array(sbwidth, sbheight * 16 * sizeof(*s->blmotion)); - s->mctmp = av_malloc((w+64+MAX_BLOCKSIZE) * (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); - s->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE); - - if (!s->sbsplit || !s->blmotion || !s->mctmp || !s->mcscratch) + if (!s->sbsplit || !s->blmotion) return AVERROR(ENOMEM); return 0; } +static int alloc_buffers(DiracContext *s, int stride) +{ + int w = s->source.width; + int h = s->source.height; + + av_assert0(stride >= w); + stride += 64; + + if (s->buffer_stride >= stride) + return 0; + s->buffer_stride = 0; + + av_freep(&s->edge_emu_buffer_base); + memset(s->edge_emu_buffer, 0, sizeof(s->edge_emu_buffer)); + av_freep(&s->mctmp); + av_freep(&s->mcscratch); + + s->edge_emu_buffer_base = av_malloc_array(stride, MAX_BLOCKSIZE); + + s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); + s->mcscratch = av_malloc_array(stride, MAX_BLOCKSIZE); + + if (!s->edge_emu_buffer_base || !s->mctmp || !s->mcscratch) + return AVERROR(ENOMEM); + + s->buffer_stride = stride; + return 0; +} + static void free_sequence_buffers(DiracContext *s) { int i, j, k; @@ -381,6 +404,7 @@ static void free_sequence_buffers(DiracContext *s) av_freep(&s->plane[i].idwt_tmp); } + s->buffer_stride = 0; av_freep(&s->sbsplit); av_freep(&s->blmotion); av_freep(&s->edge_emu_buffer_base); @@ -1342,8 +1366,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 */ @@ -1817,6 +1841,9 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int s->plane[1].stride = pic->avframe.linesize[1]; s->plane[2].stride = pic->avframe.linesize[2]; + if (alloc_buffers(s, FFMAX3(FFABS(s->plane[0].stride), FFABS(s->plane[1].stride), FFABS(s->plane[2].stride))) < 0) + return AVERROR(ENOMEM); + /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */ if (dirac_decode_picture_header(s)) return -1; diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 0fe03f9978..515280cb72 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -39,6 +39,7 @@ typedef struct DNXHDContext { GetBitContext gb; int64_t cid; ///< compression id unsigned int width, height; + enum AVPixelFormat pix_fmt; unsigned int mb_width, mb_height; uint32_t mb_scan_index[68]; /* max for 1080p */ int cur_field; ///< current interlaced field @@ -135,7 +136,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 = AV_PIX_FMT_YUV422P10; + ctx->pix_fmt = AV_PIX_FMT_YUV422P10; ctx->avctx->bits_per_raw_sample = 10; if (ctx->bit_depth != 10) { ff_dsputil_init(&ctx->dsp, ctx->avctx); @@ -143,7 +144,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 = AV_PIX_FMT_YUV422P; + ctx->pix_fmt = AV_PIX_FMT_YUV422P; ctx->avctx->bits_per_raw_sample = 8; if (ctx->bit_depth != 8) { ff_dsputil_init(&ctx->dsp, ctx->avctx); @@ -381,9 +382,15 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, avctx->width, avctx->height, ctx->width, ctx->height); first_field = 1; } + if (avctx->pix_fmt != AV_PIX_FMT_NONE && avctx->pix_fmt != ctx->pix_fmt) { + av_log(avctx, AV_LOG_WARNING, "pix_fmt changed: %s -> %s\n", + av_get_pix_fmt_name(avctx->pix_fmt), av_get_pix_fmt_name(ctx->pix_fmt)); + first_field = 1; + } if (av_image_check_size(ctx->width, ctx->height, 0, avctx)) return -1; + avctx->pix_fmt = ctx->pix_fmt; avcodec_set_dimensions(avctx, ctx->width, ctx->height); if (first_field) { @@ -406,7 +413,7 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *picture = ctx->picture; *got_frame = 1; - return buf_size; + return avpkt->size; } static av_cold int dnxhd_decode_close(AVCodecContext *avctx) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 690e64f869..1d3fdbd97e 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -235,7 +235,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); @@ -629,14 +629,35 @@ static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx) static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) { DNXHDEncContext *ctx = avctx->priv_data; - int mb_y = jobnr, mb_x; + int mb_y = jobnr, mb_x, x, y; + int partial_last_row = (mb_y == ctx->m.mb_height - 1) && + ((avctx->height >> ctx->interlaced) & 0xF); + ctx = ctx->thread[threadnr]; if (ctx->cid_table->bit_depth == 8) { uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize); for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) { unsigned mb = mb_y * ctx->m.mb_width + mb_x; - int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); - int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)sum*sum)>>8)+128)>>8; + int sum; + int varc; + + if (!partial_last_row && mb_x * 16 <= avctx->width - 16) { + sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); + varc = ctx->m.dsp.pix_norm1(pix, ctx->m.linesize); + } else { + int bw = FFMIN(avctx->width - 16 * mb_x, 16); + int bh = FFMIN((avctx->height >> ctx->interlaced) - 16 * mb_y, 16); + sum = varc = 0; + for (y = 0; y < bh; y++) { + for (x = 0; x < bw; x++) { + uint8_t val = pix[x + y * ctx->m.linesize]; + sum += val; + varc += val * val; + } + } + } + varc = (varc - (((unsigned)sum * sum) >> 8) + 128) >> 8; + ctx->mb_cmp[mb].value = varc; ctx->mb_cmp[mb].mb = mb; } diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c index bd44b16ffc..f210bbc774 100644 --- a/libavcodec/dpxenc.c +++ b/libavcodec/dpxenc.c @@ -212,6 +212,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, buf[803] = s->bits_per_component; write16(buf + 804, (s->bits_per_component == 10 || s->bits_per_component == 12) ? 1 : 0); /* packing method */ + write32(buf + 808, HEADER_SIZE); /* data offset */ /* Image source information header */ write32(buf + 1628, avctx->sample_aspect_ratio.num); diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 76d4d1fc4d..567b1f83da 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -128,27 +128,30 @@ 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; + memcpy(huff_code_table, src, 15); + src += 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]; @@ -167,11 +170,12 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c return dst_cur - dst; } -static int 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, *dst_start = dst; + 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) { @@ -180,13 +184,15 @@ static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char 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) + 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); @@ -199,10 +205,11 @@ static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char return 0; } -static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int 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 + 1 < src_end && dst < dst_end) { @@ -216,7 +223,7 @@ static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char av_log(NULL, AV_LOG_ERROR, "RLE overread\n"); return AVERROR_INVALIDDATA; } - memcpy(dst, src, FFMIN(len, dst_end - dst)); + memcpy(dst, src, FFMIN3(len, dst_end - dst, src_end - src)); src += len; } dst += len; @@ -228,15 +235,16 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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, res = 0; + int i, y, palette_type, palette_colors_count, + bitmap_frame_type, bitmap_frame_size, res = 0; - palette_type = buf[0]; - palette_colors_count = AV_RL16(buf+1); - bitmap_frame_type = buf[3]; - buf += 4; + palette_type = buf[0]; + palette_colors_count = AV_RL16(buf + 1); + bitmap_frame_type = buf[3]; + buf += 4; bitmap_frame_size = buf_size - 4; @@ -247,46 +255,50 @@ 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] = 0xFFU << 24 | bytestream_get_le24(&buf); + cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf); bitmap_frame_size -= 3; } } else { for (i = 0; i < palette_colors_count; ++i) { - cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf+1); + cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf + 1); buf += 4; bitmap_frame_size -= 4; } } - /* 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: bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_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: res = cin_decode_lzss(buf, bitmap_frame_size, @@ -302,12 +314,12 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, 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))) { + if ((res = avctx->reget_buffer(avctx, &cin->frame)) < 0) { av_log(cin->avctx, AV_LOG_ERROR, "failed to allocate a frame\n"); return res; } @@ -316,10 +328,11 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, 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]); *got_frame = 1; *(AVFrame *)data = cin->frame; @@ -358,8 +371,8 @@ 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; @@ -375,13 +388,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; @@ -392,7 +405,6 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } - AVCodec ff_dsicinvideo_decoder = { .name = "dsicinvideo", .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 7314215387..e6973c72c0 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -1922,7 +1922,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); @@ -1947,7 +1947,7 @@ static void diff_bytes_c(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, } }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); diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 18c90c2b6c..f8848f213c 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -350,11 +350,6 @@ static av_cold int dvvideo_init_encoder(AVCodecContext *avctx) 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); -} - #if CONFIG_SMALL /* Converts run and level (where level != 0) pair into VLC, returning bit size */ static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c index e50c3396e4..32a945ed65 100644 --- a/libavcodec/dvdsub_parser.c +++ b/libavcodec/dvdsub_parser.c @@ -45,8 +45,11 @@ static int dvdsub_parse(AVCodecParserContext *s, DVDSubParseContext *pc = s->priv_data; if (pc->packet_index == 0) { - if (buf_size < 2) - return 0; + if (buf_size < 2 || AV_RB16(buf) && buf_size < 6) { + if (buf_size) + av_log(avctx, AV_LOG_DEBUG, "Parser input %d too small\n", buf_size); + return buf_size; + } pc->packet_len = AV_RB16(buf); if (pc->packet_len == 0) /* HD-DVD subpicture packet */ pc->packet_len = AV_RB32(buf+2); diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index cc9e11bc92..b4032a6a19 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -98,6 +98,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); @@ -339,10 +345,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 3f489aeab9..e6caa7f0f5 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -255,6 +255,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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) && tmpptr){ for(i = 0; i < avctx->width; i++) @@ -298,6 +304,11 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_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/eacmv.c b/libavcodec/eacmv.c index a129161386..facbd69cb4 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -114,8 +114,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++; } @@ -123,7 +123,7 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end) { - int pal_start, pal_count, i; + int pal_start, pal_count, i, fps; if(buf_end - buf < 16) { av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); @@ -135,8 +135,9 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t if (s->avctx->width!=s->width || s->avctx->height!=s->height) avcodec_set_dimensions(s->avctx, s->width, s->height); - s->avctx->time_base.num = 1; - s->avctx->time_base.den = AV_RL16(&buf[10]); + fps = AV_RL16(&buf[10]); + if (fps > 0) + s->avctx->time_base = (AVRational){ 1, fps }; pal_start = AV_RL16(&buf[12]); pal_count = AV_RL16(&buf[14]); diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 2f9559fe8e..49f5a0a965 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" @@ -139,6 +140,11 @@ static inline int decode_block_intra(MadContext *s, 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; @@ -153,6 +159,11 @@ static inline int decode_block_intra(MadContext *s, 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; @@ -164,10 +175,6 @@ static inline int decode_block_intra(MadContext *s, 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; } @@ -232,32 +239,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 *s = avctx->priv_data; + GetByteContext gb; int width, height, ret; int chunk_type; int inter; - if (buf_size < 26) { - av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n"); - *got_frame = 0; + bytestream2_init(&gb, buf, buf_size); + + chunk_type = bytestream2_get_le32(&gb); + inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG); + bytestream2_skip(&gb, 10); + + av_reduce(&avctx->time_base.num, &avctx->time_base.den, + bytestream2_get_le16(&gb), 1000, 1<<30); + + width = bytestream2_get_le16(&gb); + height = bytestream2_get_le16(&gb); + bytestream2_skip(&gb, 1); + calc_quant_matrix(s, 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; } - chunk_type = AV_RL32(&buf[0]); - inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG); - buf += 8; - - av_reduce(&avctx->time_base.num, &avctx->time_base.den, - AV_RL16(&buf[6]), 1000, 1<<30); - - width = AV_RL16(&buf[8]); - height = AV_RL16(&buf[10]); - calc_quant_matrix(s, buf[13]); - buf += 16; - if (avctx->width != width || avctx->height != height) { - if((width * height)/2048*7 > buf_end-buf) + if((width * height)/2048*7 > bytestream2_get_bytes_left(&gb)) return AVERROR_INVALIDDATA; if ((ret = av_image_check_size(width, height, 0, avctx)) < 0) return ret; @@ -276,14 +285,29 @@ static int decode_frame(AVCodecContext *avctx, } } + if (inter && !s->last_frame.data[0]) { + int ret; + av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n"); + s->last_frame.reference = 1; + ret = ff_get_buffer(avctx, &s->last_frame); + if (ret < 0) + return ret; + memset(s->last_frame.data[0], 0, s->last_frame.height * + s->last_frame.linesize[0]); + memset(s->last_frame.data[1], 0x80, s->last_frame.height / 2 * + s->last_frame.linesize[1]); + memset(s->last_frame.data[2], 0x80, s->last_frame.height / 2 * + s->last_frame.linesize[2]); + } + av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, - buf_end - buf); + bytestream2_get_bytes_left(&gb)); if (!s->bitstream_buf) return AVERROR(ENOMEM); - s->dsp.bswap16_buf(s->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2); - memset((uint8_t*)s->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&s->gb, s->bitstream_buf, 8*(buf_end-buf)); - + s->dsp.bswap16_buf(s->bitstream_buf, (const uint16_t *)(buf + bytestream2_tell(&gb)), + bytestream2_get_bytes_left(&gb) / 2); + memset((uint8_t*)s->bitstream_buf + bytestream2_get_bytes_left(&gb), 0, FF_INPUT_BUFFER_PADDING_SIZE); + init_get_bits(&s->gb, s->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(s, inter) < 0) diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index 01f7424904..c2488fc0bc 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -924,6 +924,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"); diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 3e51a3e793..a8d5d240b3 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -247,7 +247,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/fft-test.c b/libavcodec/fft-test.c index 66474cecd8..9d571a2f38 100644 --- a/libavcodec/fft-test.c +++ b/libavcodec/fft-test.c @@ -112,6 +112,7 @@ static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) } } +#if CONFIG_MDCT static void imdct_ref(FFTSample *out, FFTSample *in, int nbits) { int n = 1<fft_permute(s, tab); @@ -377,6 +389,7 @@ int main(int argc, char **argv) err = check_diff((FFTSample *)tab_ref, (FFTSample *)tab, fft_size * 2, 1.0); break; #if CONFIG_FFT_FLOAT +#if CONFIG_RDFT case TRANSFORM_RDFT: fft_size_2 = fft_size >> 1; if (do_inverse) { @@ -408,6 +421,8 @@ int main(int argc, char **argv) err = check_diff((float *)tab_ref, (float *)tab2, fft_size, 1.0); } break; +#endif /* CONFIG_RDFT */ +#if CONFIG_DCT case TRANSFORM_DCT: memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); d->dct_calc(d, (FFTSample *)tab); @@ -418,6 +433,7 @@ int main(int argc, char **argv) } err = check_diff((float *)tab_ref, (float *)tab, fft_size, 1.0); break; +#endif /* CONFIG_DCT */ #endif } @@ -469,19 +485,25 @@ int main(int argc, char **argv) } switch (transform) { +#if CONFIG_MDCT case TRANSFORM_MDCT: ff_mdct_end(m); break; +#endif /* CONFIG_MDCT */ case TRANSFORM_FFT: ff_fft_end(s); break; #if CONFIG_FFT_FLOAT +#if CONFIG_RDFT case TRANSFORM_RDFT: ff_rdft_end(r); break; +#endif /* CONFIG_RDFT */ +#if CONFIG_DCT case TRANSFORM_DCT: ff_dct_end(d); break; +#endif /* CONFIG_DCT */ #endif } diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index a1da544697..1aaa0e29af 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -447,6 +447,10 @@ static int read_extra_header(FFV1Context *f) ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); f->version = get_symbol(c, state, 0); + if (f->version < 2) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid version in global header\n"); + return AVERROR_INVALIDDATA; + } if (f->version > 2) { c->bytestream_end -= 4; f->minor_version = get_symbol(c, state, 0); @@ -524,6 +528,7 @@ static int read_header(FFV1Context *f) memset(state, 128, sizeof(state)); if (f->version < 2) { + int chroma_planes, chroma_h_shift, chroma_v_shift, transparency, colorspace, bits_per_raw_sample; unsigned v= get_symbol(c, state, 0); if (v >= 2) { av_log(f->avctx, AV_LOG_ERROR, "invalid version %d in ver01 header\n", v); @@ -536,15 +541,32 @@ static int read_header(FFV1Context *f) f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i]; } - f->colorspace = get_symbol(c, state, 0); //YUV cs type + 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; + chroma_planes = get_rac(c, state); + chroma_h_shift = get_symbol(c, state, 0); + chroma_v_shift = get_symbol(c, state, 0); + transparency = get_rac(c, state); - if (f->version > 0) - f->avctx->bits_per_raw_sample = get_symbol(c, state, 0); + if (f->plane_count) { + if (colorspace != f->colorspace || + bits_per_raw_sample != f->avctx->bits_per_raw_sample || + chroma_planes != f->chroma_planes || + 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 = colorspace; + f->avctx->bits_per_raw_sample = bits_per_raw_sample; + f->chroma_planes = chroma_planes; + f->chroma_h_shift = chroma_h_shift; + f->chroma_v_shift = chroma_v_shift; + f->transparency = transparency; - f->chroma_planes = get_rac(c, state); - 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->plane_count = 2 + f->transparency; } diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 031db061fe..c5481af4f4 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -275,7 +275,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 AVERROR_INVALIDDATA; } diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 52ec1ee683..0d28c85f87 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -655,7 +655,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 9d5ecd04cf..cfde037587 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -467,10 +467,10 @@ static int decode_frame(FLACContext *s) ret = allocate_buffers(s); if (ret < 0) return ret; - ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; dump_headers(s->avctx, (FLACStreaminfo *)s); } + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); // dump_headers(s->avctx, (FLACStreaminfo *)s); diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index 7855416567..fc3a8a311f 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -389,6 +389,12 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, } 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); diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 1d0d1963f6..3e2961771a 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -288,7 +288,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 e6b181f2ae..34384b3956 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -131,7 +131,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/flicvideo.c b/libavcodec/flicvideo.c index eb70249ef7..e1bb2dd7d3 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -387,6 +387,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) break; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); + if (!byte_run) { + av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n"); + return AVERROR_INVALIDDATA; + } + if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 6500c853e2..bfceb38f38 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -145,6 +145,11 @@ static int decode_frame(AVCodecContext *avctx, enum AVPixelFormat pix_fmt; int ret; + 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; header_size = (header & (1<<30))? 8 : 4; /* bit 30 means pad to 8 bytes */ @@ -216,7 +221,7 @@ static int decode_frame(AVCodecContext *avctx, return ret; } - switch(version) { + switch (version) { case 0: default: /* Fraps v0 is a reordered YUV420 */ @@ -226,13 +231,13 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - buf32=(const uint32_t*)buf; - for(y=0; yheight/2; y++){ - luma1=(uint32_t*)&f->data[0][ y*2*f->linesize[0] ]; - luma2=(uint32_t*)&f->data[0][ (y*2+1)*f->linesize[0] ]; - cr=(uint32_t*)&f->data[1][ y*f->linesize[1] ]; - cb=(uint32_t*)&f->data[2][ y*f->linesize[2] ]; - for(x=0; xwidth; x+=8){ + buf32 = (const uint32_t*)buf; + for (y = 0; y < avctx->height / 2; y++) { + luma1 = (uint32_t*)&f->data[0][ y * 2 * f->linesize[0] ]; + luma2 = (uint32_t*)&f->data[0][ (y * 2 + 1) * f->linesize[0] ]; + cr = (uint32_t*)&f->data[1][ y * f->linesize[1] ]; + cb = (uint32_t*)&f->data[2][ y * f->linesize[2] ]; + for(x=0; xwidth; x+=8) { *luma1++ = *buf32++; *luma1++ = *buf32++; *luma2++ = *buf32++; @@ -245,10 +250,10 @@ static int decode_frame(AVCodecContext *avctx, case 1: /* Fraps v1 is an upside-down BGR24 */ - for(y=0; yheight; y++) - memcpy(&f->data[0][ (avctx->height-y)*f->linesize[0] ], - &buf[y*avctx->width*3], - 3*avctx->width); + for (y = 0; y < avctx->height; y++) + memcpy(&f->data[0][ (avctx->height - y - 1) * f->linesize[0]], + &buf[y * avctx->width * 3], + 3 * avctx->width); break; case 2: diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c index c2e86d96d3..560110ff77 100644 --- a/libavcodec/g723_1.c +++ b/libavcodec/g723_1.c @@ -2292,7 +2292,8 @@ static int pack_bitstream(G723_1_Context *p, unsigned char *frame, int size) if (p->cur_rate == RATE_6300) { info_bits = 0; put_bits(&pb, 2, info_bits); - } + }else + av_assert0(0); put_bits(&pb, 8, p->lsp_index[2]); put_bits(&pb, 8, p->lsp_index[1]); diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 777176dd30..ccc009791a 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -366,25 +366,49 @@ 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; +} + +/** + * 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 byte_size the size of the buffer in bytes + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer, + int byte_size) +{ + if (byte_size > INT_MAX / 8 || byte_size < 0) + byte_size = -1; + return init_get_bits(s, buffer, byte_size * 8); } static inline void align_get_bits(GetBitContext *s) diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index e5e84aea12..0b66d06712 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -65,8 +65,8 @@ typedef struct GifState { int stored_img_size; int stored_bg_color; - GetByteContext gb; /* LZW compatible decoder */ + GetByteContext gb; LZWState *lzw; /* aux buffers */ @@ -75,6 +75,7 @@ typedef struct GifState { AVCodecContext *avctx; int keyframe; + int keyframe_ok; int trans_color; /**< color value that is used instead of transparent color */ } GifState; @@ -118,7 +119,7 @@ static void gif_copy_img_rect(const uint32_t *src, uint32_t *dst, const uint32_t *src_px, *src_pr, *src_py = src + y_start, *dst_py = dst + y_start; - const uint32_t *src_pb = src_py + t * linesize; + const uint32_t *src_pb = src_py + h * linesize; uint32_t *dst_px; for (; src_py < src_pb; src_py += linesize, dst_py += linesize) { @@ -143,11 +144,11 @@ static int gif_read_image(GifState *s) if (bytestream2_get_bytes_left(&s->gb) < 9) return AVERROR_INVALIDDATA; - left = bytestream2_get_le16u(&s->gb); - top = bytestream2_get_le16u(&s->gb); - width = bytestream2_get_le16u(&s->gb); + left = bytestream2_get_le16u(&s->gb); + top = bytestream2_get_le16u(&s->gb); + width = bytestream2_get_le16u(&s->gb); height = bytestream2_get_le16u(&s->gb); - flags = bytestream2_get_byteu(&s->gb); + flags = bytestream2_get_byteu(&s->gb); is_interleaved = flags & 0x40; has_local_palette = flags & 0x80; bits_per_pixel = (flags & 0x07) + 1; @@ -184,8 +185,11 @@ static int gif_read_image(GifState *s) /* verify that all the image is inside the screen dimensions */ if (left + width > s->screen_width || - top + height > s->screen_height) + top + height > s->screen_height || + !width || !height) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n"); return AVERROR_INVALIDDATA; + } /* process disposal method */ if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) { @@ -252,26 +256,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; } @@ -313,7 +312,7 @@ static int gif_read_extension(GifState *s) if (bytestream2_get_bytes_left(&s->gb) < 5) return AVERROR_INVALIDDATA; - gce_flags = bytestream2_get_byteu(&s->gb); + gce_flags = bytestream2_get_byteu(&s->gb); bytestream2_skipu(&s->gb, 2); // delay during which the frame is shown gce_transparent_index = bytestream2_get_byteu(&s->gb); if (gce_flags & 0x01) @@ -367,7 +366,7 @@ static int gif_read_header1(GifState *s) /* read screen header */ s->transparent_color_index = -1; - s->screen_width = bytestream2_get_le16u(&s->gb); + s->screen_width = bytestream2_get_le16u(&s->gb); s->screen_height = bytestream2_get_le16u(&s->gb); if( (unsigned)s->screen_width > 32767 || (unsigned)s->screen_height > 32767){ @@ -410,10 +409,10 @@ static int gif_read_header1(GifState *s) static int gif_parse_next_image(GifState *s, int *got_picture) { - int ret; *got_picture = 1; - while (bytestream2_get_bytes_left(&s->gb)) { + while (bytestream2_get_bytes_left(&s->gb) > 0) { int code = bytestream2_get_byte(&s->gb); + int ret; av_dlog(s->avctx, "code=%02x '%c'\n", code, code); @@ -458,9 +457,9 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A bytestream2_init(&s->gb, avpkt->data, avpkt->size); - s->picture.pts = avpkt->pts; - s->picture.pkt_pts = avpkt->pts; - s->picture.pkt_dts = avpkt->dts; + s->picture.pts = avpkt->pts; + s->picture.pkt_pts = avpkt->pts; + s->picture.pkt_dts = avpkt->dts; s->picture.pkt_duration = avpkt->duration; if (avpkt->size >= 6) { @@ -471,6 +470,8 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A } if (s->keyframe) { + s->keyframe_ok = 0; + s->gce_prev_disposal = GCE_DISPOSAL_NONE; if ((ret = gif_read_header1(s)) < 0) return ret; @@ -488,7 +489,13 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A s->picture.pict_type = AV_PICTURE_TYPE_I; s->picture.key_frame = 1; + s->keyframe_ok = 1; } else { + if (!s->keyframe_ok) { + av_log(avctx, AV_LOG_ERROR, "cannot decode frame without keyframe\n"); + return AVERROR_INVALIDDATA; + } + if ((ret = avctx->reget_buffer(avctx, &s->picture)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; @@ -504,7 +511,7 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A else if (*got_frame) *picture = s->picture; - return avpkt->size; + return bytestream2_tell(&s->gb); } static av_cold int gif_decode_close(AVCodecContext *avctx) diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 7cca7bb82e..2637aae236 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -291,9 +291,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, "illegal mtype %d\n", h->mtype); + av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n", + h->mtype); return SLICE_ERROR; } + av_assert0(h->mtype < FF_ARRAY_ELEMS(ff_h261_mtype_map)); h->mtype = ff_h261_mtype_map[h->mtype]; // Read mquant diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 0232aa4c9d..8809e8e5d4 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -392,7 +392,6 @@ uint64_t time= rdtsc(); return buf_size; } - retry: if(s->divx_packed && s->bitstream_buffer_size){ int i; @@ -407,16 +406,20 @@ retry: } } - if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder - init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8); - }else - init_get_bits(&s->gb, buf, buf_size*8); - s->bitstream_buffer_size=0; + if (s->bitstream_buffer_size && (s->divx_packed || buf_size < 20)) // divx 5.01+/xvid frame reorder + ret = init_get_bits8(&s->gb, s->bitstream_buffer, + s->bitstream_buffer_size); + else + ret = init_get_bits8(&s->gb, buf, buf_size); - if (!s->context_initialized) { - if ((ret = ff_MPV_common_init(s)) < 0) //we need the idct permutaton for reading a custom matrix + s->bitstream_buffer_size=0; + if (ret < 0) + return ret; + + if (!s->context_initialized) + // we need the idct permutaton for reading a custom matrix + if ((ret = ff_MPV_common_init(s)) < 0) return ret; - } /* We need to set current_picture_ptr before reading the header, * otherwise we cannot store anyting in there */ @@ -436,8 +439,11 @@ retry: if(s->avctx->extradata_size && s->picture_number==0){ GetBitContext gb; - init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); - ret = ff_mpeg4_decode_picture_header(s, &gb); + ret = init_get_bits8(&gb, s->avctx->extradata, + s->avctx->extradata_size); + if (ret < 0) + return ret; + ff_mpeg4_decode_picture_header(s, &gb); } ret = ff_mpeg4_decode_picture_header(s, &s->gb); } else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) { @@ -597,17 +603,6 @@ retry: /* FIXME: By the way H263 decoder is evolving it should have */ /* an H263EncContext */ - if ((!avctx->coded_width || !avctx->coded_height) && 0) { - ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat - - s->parse_context.buffer=0; - ff_MPV_common_end(s); - s->parse_context= pc; - avcodec_set_dimensions(avctx, s->width, s->height); - - goto retry; - } - if (s->width != avctx->coded_width || s->height != avctx->coded_height || s->context_reinit) { @@ -725,10 +720,10 @@ frame_end: } if(startcode_found){ - av_fast_malloc( + av_fast_padded_mallocz( &s->bitstream_buffer, &s->allocated_bitstream_buffer_size, - buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE); + buf_size - current_pos); if (!s->bitstream_buffer) return AVERROR(ENOMEM); memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); diff --git a/libavcodec/h264.c b/libavcodec/h264.c index f6cfa1a35d..bf75f3f3d1 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -67,9 +67,15 @@ static const uint8_t div6[QP_MAX_NUM + 1] = { }; static const enum AVPixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = { +#if CONFIG_H264_DXVA2_HWACCEL AV_PIX_FMT_DXVA2_VLD, +#endif +#if CONFIG_H264_VAAPI_HWACCEL AV_PIX_FMT_VAAPI_VLD, +#endif +#if CONFIG_H264_VDA_HWACCEL AV_PIX_FMT_VDA_VLD, +#endif AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE }; @@ -135,10 +141,10 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h) 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); @@ -157,18 +163,18 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) if ((h->left_samples_available & 0x8080) != 0x8080) { mode = left[mode]; - if (is_chroma && (h->left_samples_available & 0x8080)) { - // mad cow disease mode, aka MBAFF + constrained_intra_pred - mode = ALZHEIMER_DC_L0T_PRED8x8 + - (!(h->left_samples_available & 0x8000)) + - 2 * (mode == DC_128_PRED8x8); - } if (mode < 0) { av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y); return -1; } + if (is_chroma && (h->left_samples_available & 0x8080)) { + // mad cow disease mode, aka MBAFF + constrained_intra_pred + mode = ALZHEIMER_DC_L0T_PRED8x8 + + (!(h->left_samples_available & 0x8000)) + + 2 * (mode == DC_128_PRED8x8); + } } return mode; @@ -309,10 +315,11 @@ static inline int get_lowest_part_list_y(H264Context *h, Picture *pic, int n, int height, int y_offset, int list) { int raw_my = h->mv_cache[list][scan8[n]][1]; - int filter_height = (raw_my & 3) ? 2 : 0; + int filter_height_up = (raw_my & 3) ? 2 : 0; + int filter_height_down = (raw_my & 3) ? 3 : 0; int full_my = (raw_my >> 2) + y_offset; - int top = full_my - filter_height; - int bottom = full_my + filter_height + height; + int top = full_my - filter_height_up; + int bottom = full_my + filter_height_down + height; return FFMAX(abs(top), bottom); } @@ -1242,6 +1249,18 @@ static int decode_update_thread_context(AVCodecContext *dst, 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 (s1->context_initialized) { if (ff_h264_alloc_tables(h) < 0) { av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n"); @@ -1330,6 +1349,8 @@ int ff_h264_frame_start(H264Context *h) int i; const int pixel_shift = h->pixel_shift; + h->next_output_pic = NULL; + if (ff_MPV_frame_start(s, s->avctx) < 0) return -1; ff_er_frame_start(s); @@ -1382,8 +1403,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; @@ -2169,6 +2188,7 @@ static void flush_change(H264Context *h) h->sync= 0; h->list_count = 0; h->current_slice = 0; + h->mmco_reset = 1; } /* forget old pics after a seek */ @@ -2350,7 +2370,7 @@ static int field_end(H264Context *h, int in_setup) * past end by one (callers fault) and resync_mb_y != 0 * causes problems for the first MB line, too. */ - if (!FIELD_PICTURE) + if (!FIELD_PICTURE && h->current_slice && !h->sps.new) ff_er_frame_end(s); ff_MPV_frame_end(s); @@ -2474,7 +2494,7 @@ static int h264_set_parameter_from_sps(H264Context *h) return 0; } -static enum PixelFormat get_pixel_format(H264Context *h) +static enum PixelFormat get_pixel_format(H264Context *h, int force_callback) { MpegEncContext *const s = &h->s; switch (h->sps.bit_depth_luma) { @@ -2536,11 +2556,17 @@ static enum PixelFormat get_pixel_format(H264Context *h) return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P : AV_PIX_FMT_YUV422P; } else { - return s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts ? + int i; + const enum AVPixelFormat * fmt = s->avctx->codec->pix_fmts ? s->avctx->codec->pix_fmts : s->avctx->color_range == AVCOL_RANGE_JPEG ? hwaccel_pixfmt_list_h264_jpeg_420 : - ff_hwaccel_pixfmt_list_420); + ff_hwaccel_pixfmt_list_420; + + for (i=0; fmt[i] != AV_PIX_FMT_NONE; i++) + if (fmt[i] == s->avctx->pix_fmt && !force_callback) + return fmt[i]; + return s->avctx->get_format(s->avctx, fmt); } break; default: @@ -2589,7 +2615,7 @@ static int h264_slice_header_init(H264Context *h, int reinit) return ret; } } else { - if ((ret = ff_MPV_common_init(s) < 0)) { + if ((ret = ff_MPV_common_init(s)) < 0) { av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n"); return ret; } @@ -2706,6 +2732,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->slice_type = slice_type; h->slice_type_nos = slice_type & 3; + 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; @@ -2764,7 +2796,8 @@ 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 (h0->s.avctx->pix_fmt != get_pixel_format(h0, 0)) + must_reinit = 1; s->mb_width = h->sps.mb_width; s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag); @@ -2801,7 +2834,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) flush_change(h); - if ((ret = get_pixel_format(h)) < 0) + if ((ret = get_pixel_format(h, 1)) < 0) return ret; s->avctx->pix_fmt = ret; @@ -2822,7 +2855,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) return -1; } - if ((ret = get_pixel_format(h)) < 0) + if ((ret = get_pixel_format(h, 1)) < 0) return ret; s->avctx->pix_fmt = ret; @@ -2906,7 +2939,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF); /* Mark old field/frame as completed */ - if (!last_pic_droppable && s0->current_picture_ptr->owner2 == s0) { + if (s0->current_picture_ptr->owner2 == s0) { ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX, last_pic_structure == PICT_BOTTOM_FIELD); } @@ -2915,7 +2948,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) 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_droppable && last_pic_structure != PICT_FRAME) { + if (last_pic_structure != PICT_FRAME) { ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } @@ -2925,7 +2958,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference * purposes. */ - if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { + if (last_pic_structure != PICT_FRAME) { ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } @@ -2966,14 +2999,21 @@ static int decode_slice_header(H264Context *h, H264Context *h0) 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 (!h->sps.gaps_in_frame_num_allowed_flag) + for(i=0; ilast_pocs); i++) + h->last_pocs[i] = INT_MIN; + if (ff_h264_frame_start(h) < 0) { + s0->first_field = 0; return -1; + } h->prev_frame_num++; h->prev_frame_num %= 1 << h->sps.log2_max_frame_num; s->current_picture_ptr->frame_num = h->prev_frame_num; ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 1); - ff_generate_sliding_window_mmcos(h); + if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 && + s->avctx->err_recognition & AV_EF_EXPLODE) + return ret; if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 && (s->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; @@ -3106,7 +3146,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){ av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]); - h->ref_count[0] = h->ref_count[1] = 1; + h->ref_count[0] = h->ref_count[1] = 0; return AVERROR_INVALIDDATA; } @@ -3114,8 +3154,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->list_count = 2; else h->list_count = 1; - } else - h->ref_count[1]= h->ref_count[0]= h->list_count= 0; + } else { + h->list_count = 0; + h->ref_count[0] = h->ref_count[1] = 0; + } if (!default_ref_list_done) ff_h264_fill_default_ref_list(h); @@ -3152,7 +3194,15 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } } - if (h->nal_ref_idc && ff_h264_decode_ref_pic_marking(h0, &s->gb) < 0 && + // If frame-mt is enabled, only update mmco tables for the first slice + // in a field. Subsequent slices can temporarily clobber h->mmco_index + // or h->mmco, which will cause ref list mix-ups and decoding errors + // further down the line. This may break decoding if the first slice is + // corrupt, thus we only do this if frame-mt is enabled. + if (h->nal_ref_idc && + ff_h264_decode_ref_pic_marking(h0, &s->gb, + !(s->avctx->active_thread_type & FF_THREAD_FRAME) || + h0->current_slice == 0) < 0 && (s->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; @@ -3195,8 +3245,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) get_se_golomb(&s->gb); /* slice_qs_delta */ 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) { @@ -3209,10 +3259,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0) 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) { + 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); @@ -3249,7 +3301,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } } } - h->qp_thresh = 15 + 52 - + h->qp_thresh = 15 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - FFMAX3(0, h->pps.chroma_qp_index_offset[0], @@ -3323,7 +3375,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) 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->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") : ""); @@ -3876,6 +3928,8 @@ static int execute_decode_slices(H264Context *h, int context_count) H264Context *hx; int i; + av_assert0(s->mb_y < s->mb_height); + if (s->avctx->hwaccel || s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) return 0; @@ -3998,7 +4052,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, s->workaround_bugs |= FF_BUG_TRUNCATED; if (!(s->workaround_bugs & FF_BUG_TRUNCATED)) - while(dst_length > 0 && ptr[dst_length - 1] == 0) + while (dst_length > 0 && ptr[dst_length - 1] == 0) dst_length--; bit_length = !dst_length ? 0 : (8 * dst_length - @@ -4151,12 +4205,24 @@ again: } 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 */ + h->s.data_partitioning = 0; break; + } hx->s.data_partitioning = 1; break; @@ -4226,9 +4292,10 @@ again: 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 @@ -4281,6 +4348,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, 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 3355d05e97..4b6a19ed4a 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -669,9 +669,10 @@ void ff_h264_remove_all_refs(H264Context *h); */ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count); -int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb); +int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, + int first_slice); -void ff_generate_sliding_window_mmcos(H264Context *h); +int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice); /** * Check if the top & left blocks are available if needed & change the diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 76a648143d..da10e50614 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1712,7 +1712,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++; \ } \ \ diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index cd1130a4bc..eb3869ff39 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -709,7 +709,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){ @@ -771,6 +771,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++){ diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index 7cd9f69189..cad519d822 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -251,8 +251,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]; @@ -712,8 +712,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 = 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 2dea93301a..f9c3621d3f 100644 --- a/libavcodec/h264_mp4toannexb_bsf.c +++ b/libavcodec/h264_mp4toannexb_bsf.c @@ -154,7 +154,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 a68645bc36..79da0bc85e 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -267,7 +267,9 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ } 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; } } @@ -385,7 +387,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ } 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 > 14U || sps->bit_depth_chroma > 14U) { + if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 14 || + sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 14 || + 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; diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 812913a612..ea697b0b80 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -63,7 +63,9 @@ 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; @@ -73,10 +75,12 @@ static int build_def_list(Picture *def, Picture **in, int len, int is_long, int while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->f.reference & (sel^3)))) i[1]++; if(i[0] < len){ + av_assert0(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){ + av_assert0(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,8 +128,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); av_assert0(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); + 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); + av_assert0(len<=32); if(len < h->ref_count[list]) @@ -139,8 +147,12 @@ 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); + 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); + av_assert0(len<=32); if(len < h->ref_count[0]) memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len)); @@ -287,7 +299,10 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ for(list=0; listlist_count; list++){ for(index= 0; index < h->ref_count[list]; index++){ if (!h->ref_list[list][index].f.data[0]) { + int i; av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc); + for (i=0; ilast_pocs); i++) + h->last_pocs[i] = INT_MIN; if (h->default_ref_list[list][0].f.data[0]) h->ref_list[list][index]= h->default_ref_list[list][0]; else @@ -480,22 +495,50 @@ static void print_long_term(H264Context *h) { } } -void ff_generate_sliding_window_mmcos(H264Context *h) { - MpegEncContext * const s = &h->s; +static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos) +{ + int i; - h->mmco_index= 0; - if(h->short_ref_count && h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count && - !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->f.reference)) { - h->mmco[0].opcode= MMCO_SHORT2UNUSED; - h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; - h->mmco_index= 1; + for (i = 0; i < n_mmcos; i++) { + if (mmco1[i].opcode != mmco2[i].opcode) + return -1; + } + + return 0; +} + +int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) +{ + MpegEncContext * const s = &h->s; + MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; + int mmco_index = 0, i; + + if (h->short_ref_count && + h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count && + !(FIELD_PICTURE && !s->first_field && + s->current_picture_ptr->f.reference)) { + mmco[0].opcode = MMCO_SHORT2UNUSED; + mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num; + mmco_index = 1; if (FIELD_PICTURE) { - h->mmco[0].short_pic_num *= 2; - h->mmco[1].opcode= MMCO_SHORT2UNUSED; - h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1; - h->mmco_index= 2; + mmco[0].short_pic_num *= 2; + mmco[1].opcode = MMCO_SHORT2UNUSED; + mmco[1].short_pic_num = mmco[0].short_pic_num + 1; + mmco_index = 2; } } + + if (first_slice) { + h->mmco_index = mmco_index; + } else if (!first_slice && mmco_index >= 0 && + (mmco_index != h->mmco_index || + (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) { + av_log(h->s.avctx, AV_LOG_ERROR, + "Inconsistent MMCO state between slices [%d, %d, %d]\n", + mmco_index, h->mmco_index, i); + return AVERROR_INVALIDDATA; + } + return 0; } int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ @@ -519,7 +562,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; @@ -656,7 +699,7 @@ 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; @@ -665,52 +708,86 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; } -int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ +int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, + int first_slice) +{ MpegEncContext * const s = &h->s; - int i; + int i, ret; + MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; + int mmco_index = 0; - h->mmco_index= 0; - if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields - s->broken_link= get_bits1(gb) -1; - if(get_bits1(gb)){ - h->mmco[0].opcode= MMCO_LONG; - h->mmco[0].long_arg= 0; - h->mmco_index= 1; + if (h->nal_unit_type == NAL_IDR_SLICE){ // FIXME fields + s->broken_link = get_bits1(gb) - 1; + if (get_bits1(gb)){ + mmco[0].opcode = MMCO_LONG; + mmco[0].long_arg = 0; + mmco_index = 1; } - }else{ - if(get_bits1(gb)){ // adaptive_ref_pic_marking_mode_flag - for(i= 0; immco[i].opcode= opcode; - if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ - h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); -/* if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_num ] == NULL){ - av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); - return -1; - }*/ - } - if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG){ - unsigned int long_arg= get_ue_golomb_31(gb); - if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); + mmco[i].opcode = opcode; + if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG){ + mmco[i].short_pic_num = + (h->curr_pic_num - get_ue_golomb(gb) - 1) & + (h->max_pic_num - 1); +#if 0 + if (mmco[i].short_pic_num >= h->short_ref_count || + h->short_ref[ mmco[i].short_pic_num ] == NULL){ + av_log(s->avctx, AV_LOG_ERROR, + "illegal short ref in memory management control " + "operation %d\n", mmco); return -1; } - h->mmco[i].long_arg= long_arg; +#endif + } + if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || + opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { + unsigned int long_arg = get_ue_golomb_31(gb); + if (long_arg >= 32 || + (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && + long_arg == 16) && + !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ + av_log(h->s.avctx, AV_LOG_ERROR, + "illegal long ref in memory management control " + "operation %d\n", opcode); + return -1; + } + mmco[i].long_arg = long_arg; } - if(opcode > (unsigned)MMCO_LONG){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); + if (opcode > (unsigned) MMCO_LONG){ + av_log(h->s.avctx, AV_LOG_ERROR, + "illegal memory management control operation %d\n", + opcode); return -1; } - if(opcode == MMCO_END) + if (opcode == MMCO_END) break; } - h->mmco_index= i; - }else{ - ff_generate_sliding_window_mmcos(h); + mmco_index = i; + } else { + if (first_slice) { + ret = ff_generate_sliding_window_mmcos(h, first_slice); + if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } + mmco_index = -1; } } + if (first_slice && mmco_index != -1) { + h->mmco_index = mmco_index; + } else if (!first_slice && mmco_index >= 0 && + (mmco_index != h->mmco_index || + (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) { + av_log(h->s.avctx, AV_LOG_ERROR, + "Inconsistent MMCO state between slices [%d, %d, %d]\n", + mmco_index, h->mmco_index, i); + return AVERROR_INVALIDDATA; + } + return 0; } diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 62320e2d6a..ee92837ab9 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -223,6 +223,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 69d0536981..9d51ece367 100644 --- a/libavcodec/h264dsp.c +++ b/libavcodec/h264dsp.c @@ -63,13 +63,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);\ @@ -90,20 +90,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/h264pred.c b/libavcodec/h264pred.c index db483c9702..d21794f2fd 100644 --- a/libavcodec/h264pred.c +++ b/libavcodec/h264pred.c @@ -480,7 +480,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, 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 {\ @@ -488,7 +488,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x16_horizontal , depth);\ }\ if (codec_id != AV_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);\ @@ -496,7 +496,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, } else\ h->pred8x8[PLANE_PRED8x8]= FUNCD(pred8x8_tm_vp8);\ if(codec_id != AV_CODEC_ID_RV40 && codec_id != AV_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);\ @@ -522,7 +522,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, 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);\ @@ -556,7 +556,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, 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/huffyuvdec.c b/libavcodec/huffyuvdec.c index 9c92bf3875..fe0a912cae 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -107,23 +107,26 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb) return 0; } -static void generate_joint_tables(HYuvContext *s) +static int generate_joint_tables(HYuvContext *s) { uint16_t symbols[1 << VLC_BITS]; uint16_t bits[1 << VLC_BITS]; uint8_t len[1 << VLC_BITS]; + int ret; + if (s->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; @@ -132,8 +135,9 @@ static void generate_joint_tables(HYuvContext *s) } } ff_free_vlc(&s->vlc[3 + p]); - ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1, - bits, 2, 2, symbols, 2, 2, 0); + 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; @@ -146,18 +150,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) { @@ -174,29 +179,34 @@ static void generate_joint_tables(HYuvContext *s) } } ff_free_vlc(&s->vlc[3]); - init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0); + 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 (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0) { - return -1; - } + if ((ret = read_len_table(s->len[i], &gb)) < 0) + return ret; + if ((ret = ff_huffyuv_generate_bits_table(s->bits[i], s->len[i])) < 0) + return ret; ff_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 = 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; } @@ -204,17 +214,19 @@ static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length) static int read_old_huffman_tables(HYuvContext *s) { GetBitContext gb; - int i; + int i, ret; - init_get_bits(&gb, classic_shift_luma, - classic_shift_luma_table_size * 8); - if (read_len_table(s->len[0], &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; - init_get_bits(&gb, classic_shift_chroma, - classic_shift_chroma_table_size * 8); - if (read_len_table(s->len[1], &gb) < 0) - return -1; + 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]; @@ -228,11 +240,13 @@ static int read_old_huffman_tables(HYuvContext *s) for (i = 0; i < 3; i++) { ff_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 = 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; } @@ -240,6 +254,7 @@ static int read_old_huffman_tables(HYuvContext *s) static av_cold int decode_init(AVCodecContext *avctx) { HYuvContext *s = avctx->priv_data; + int ret; ff_huffyuv_common_init(avctx); memset(s->vlc, 0, 3 * sizeof(VLC)); @@ -275,9 +290,9 @@ static av_cold int decode_init(AVCodecContext *avctx) 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 AVERROR_INVALIDDATA; + 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: @@ -304,8 +319,8 @@ static av_cold int decode_init(AVCodecContext *avctx) s->bitstream_bpp = avctx->bits_per_coded_sample & ~7; s->context = 0; - if (read_old_huffman_tables(s) < 0) - return AVERROR_INVALIDDATA; + if ((ret = read_old_huffman_tables(s)) < 0) + return ret; } switch (s->bitstream_bpp) { @@ -335,13 +350,16 @@ static av_cold int decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n"); return AVERROR_INVALIDDATA; } - if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P && avctx->width%4) { - av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 this colorspace and predictor\n"); + if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P && + avctx->width % 4) { + av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 " + "for this combination of colorspace and predictor type.\n"); return AVERROR_INVALIDDATA; } - if (ff_huffyuv_alloc_temp(s)) { + + if ((ret = ff_huffyuv_alloc_temp(s)) < 0) { ff_huffyuv_common_end(s); - return AVERROR(ENOMEM); + return ret; } return 0; @@ -350,24 +368,24 @@ static av_cold int decode_init(AVCodecContext *avctx) 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; - if (ff_huffyuv_alloc_temp(s)) { + if ((ret = ff_huffyuv_alloc_temp(s)) < 0) { ff_huffyuv_common_end(s); - return AVERROR(ENOMEM); + return ret; } for (i = 0; i < 6; i++) s->vlc[i].table = NULL; if (s->version == 2) { - if (read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4, - avctx->extradata_size) < 0) - return AVERROR_INVALIDDATA; + 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 AVERROR_INVALIDDATA; + if ((ret = read_old_huffman_tables(s)) < 0) + return ret; } return 0; @@ -526,14 +544,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (s->context) { table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); if (table_size < 0) - return AVERROR_INVALIDDATA; + return table_size; } if ((unsigned)(buf_size-table_size) >= INT_MAX / 8) return AVERROR_INVALIDDATA; - 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]; diff --git a/libavcodec/iff.c b/libavcodec/iff.c index c4672b8f91..37b7f25a52 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -341,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_RGB444; } else if (avctx->codec_tag != MKTAG('D','E','E','P')) { if (avctx->bits_per_coded_sample == 24) { - avctx->pix_fmt = AV_PIX_FMT_RGB0; + avctx->pix_fmt = AV_PIX_FMT_0BGR32; } else if (avctx->bits_per_coded_sample == 32) { avctx->pix_fmt = AV_PIX_FMT_BGR32; } else { @@ -832,9 +832,9 @@ static int decode_frame(AVCodecContext *avctx, break; case 4: bytestream2_init(&gb, buf, buf_size); - if (avctx->codec_tag == MKTAG('R','G','B','8')) + if (avctx->codec_tag == MKTAG('R','G','B','8') && avctx->pix_fmt == AV_PIX_FMT_RGB32) decode_rgb8(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]); - else if (avctx->codec_tag == MKTAG('R','G','B','N')) + else if (avctx->codec_tag == MKTAG('R','G','B','N') && avctx->pix_fmt == AV_PIX_FMT_RGB444) decode_rgbn(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]); else return unsupported(avctx); diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 1295c8ec6c..23eb012a8f 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -451,6 +451,10 @@ static int bit_allocation(IMCContext *q, IMCChannel *chctx, iacc += chctx->bandWidthT[i]; summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i]; } + + if (!iacc) + return AVERROR_INVALIDDATA; + chctx->bandWidthT[BANDS - 1] = 0; summa = (summa * 0.5 - freebits) / iacc; diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index a8206dbb00..1f6d3420ad 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -94,7 +94,7 @@ typedef struct Indeo3DecodeContext { int16_t width, height; uint32_t frame_num; ///< current frame number (zero-based) - uint32_t data_size; ///< size of the frame data in bytes + int data_size; ///< size of the frame data in bytes uint16_t frame_flags; ///< frame properties uint8_t cb_offset; ///< needed for selecting VQ tables uint8_t buf_sel; ///< active frame buffer: 0 - primary, 1 -secondary @@ -226,7 +226,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; @@ -239,6 +239,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; @@ -266,15 +276,17 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) dst += 4; } } + + return 0; } /* Average 4/8 pixels at once without rounding using SWAR */ #define AVG_32(dst, src, ref) \ - AV_WN32A(dst, ((AV_RN32A(src) + AV_RN32A(ref)) >> 1) & 0x7F7F7F7FUL) + AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL) #define AVG_64(dst, src, ref) \ - AV_WN64A(dst, ((AV_RN64A(src) + AV_RN64A(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL) + AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL) /* @@ -333,7 +345,7 @@ if (*data_ptr >= last_ptr) \ copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom) #define RLE_BLOCK_COPY_8 \ - pix64 = AV_RN64A(ref);\ + pix64 = AV_RN64(ref);\ if (is_first_row) {/* special prediction case: top line of a cell */\ pix64 = replicate64(pix64);\ fill_64(dst + row_offset, pix64, 7, row_offset);\ @@ -345,7 +357,7 @@ if (*data_ptr >= last_ptr) \ copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom) #define RLE_LINES_COPY_M10 \ - pix64 = AV_RN64A(ref);\ + pix64 = AV_RN64(ref);\ if (is_top_of_cell) {\ pix64 = replicate64(pix64);\ fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\ @@ -355,12 +367,12 @@ if (*data_ptr >= last_ptr) \ #define APPLY_DELTA_4 \ AV_WN16A(dst + line_offset ,\ - (AV_RN16A(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + (AV_RN16(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + line_offset + 2,\ - (AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ + (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ if (mode >= 3) {\ if (is_top_of_cell && !cell->ypos) {\ - AV_COPY32(dst, dst + row_offset);\ + AV_COPY32U(dst, dst + row_offset);\ } else {\ AVG_32(dst, ref, dst + row_offset);\ }\ @@ -370,20 +382,20 @@ 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]) & 0x7F7F7F7F);\ + (replicate32(AV_RN32(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - (replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } else { \ AV_WN32A(dst + row_offset , \ - (AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ + (AV_RN32(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - (AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (AV_RN32(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 */\ /* otherwise - interpolate */\ if (is_top_of_cell && !cell->ypos) {\ - AV_COPY64(dst, dst + row_offset);\ + AV_COPY64U(dst, dst + row_offset);\ } else \ AVG_64(dst, ref, dst + row_offset); @@ -391,22 +403,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]) & 0x7F7F7F7F);\ + (AV_RN32(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + 4 , \ - (AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (AV_RN32(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset , \ - (AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ + (AV_RN32(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]) & 0x7F7F7F7F);\ + (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } else { \ AV_WN16A(dst , \ - (AV_RN16A(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + (AV_RN16(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + 2 , \ - (AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\ + (AV_RN16(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\ AV_WN16A(dst + row_offset , \ - (AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + (AV_RN16(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + row_offset + 2, \ - (AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ + (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ } @@ -604,11 +616,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; } @@ -740,8 +764,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const int depth, const int strip_width) { Cell curr_cell; - int bytes_used; - int mv_x, mv_y; + int bytes_used, ret; if (depth <= 0) { av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); @@ -792,19 +815,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, CHECK_CELL if (!curr_cell.mv_ptr) return AVERROR_INVALIDDATA; - - mv_y = curr_cell.mv_ptr[0]; - mv_x = curr_cell.mv_ptr[1]; - if ( mv_x + 4*curr_cell.xpos < 0 - || mv_y + 4*curr_cell.ypos < 0 - || mv_x + 4*curr_cell.xpos + 4*curr_cell.width > plane->width - || mv_y + 4*curr_cell.ypos + 4*curr_cell.height > plane->height) { - av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", mv_x + 4*curr_cell.xpos, mv_y + 4*curr_cell.ypos); - return AVERROR_INVALIDDATA; - } - - copy_cell(ctx, plane, &curr_cell); - return 0; + ret = copy_cell(ctx, plane, &curr_cell); + return ret; } break; case INTER_DATA: @@ -891,17 +903,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"); @@ -909,29 +925,27 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } /* parse the bitstream header */ - bs_hdr = buf_ptr; - buf_size -= 16; + 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; @@ -953,9 +967,10 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, 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 */ @@ -973,7 +988,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; @@ -982,7 +999,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"); diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index 0766ed489a..d7acdf75d0 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -211,6 +211,7 @@ static int decode_pic_hdr(IVI45DecContext *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); } @@ -295,6 +296,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->is_empty = get_bits1(&ctx->gb); if (!band->is_empty) { + int old_blk_size = band->blk_size; /* skip header size * If header size is not given, header size is 4 bytes. */ if (get_bits1(&ctx->gb)) @@ -353,7 +355,13 @@ static int decode_band_hdr(IVI45DecContext *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; - band->transform_size= (transform_id < 10) ? 8 : 4; + 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>4 && scan_indx<10) != (band->blk_size==4)) { @@ -364,6 +372,12 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, 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->scan_size = band->blk_size; @@ -372,11 +386,23 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n"); return AVERROR_INVALIDDATA; } - if (quant_mat > 21) { - av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n"); + if (quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { + av_log_ask_for_sample(avctx, "Quantization matrix %d", + quant_mat); return AVERROR_INVALIDDATA; } band->quant_mat = quant_mat; + } else { + if (old_blk_size != band->blk_size) { + av_log(avctx, AV_LOG_ERROR, + "The band block size does not match the configuration " + "inherited\n"); + return AVERROR_INVALIDDATA; + } + if (band->quant_mat < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid quant_mat inherited\n"); + return AVERROR_INVALIDDATA; + } } if (quant_index_to_tab[band->quant_mat] > 4 && band->blk_size == 4) { av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix for 4x4 block encountered!\n"); @@ -504,8 +530,11 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, } } } else { - if (band->inherit_mv && ref_mb) { - mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ + if (band->inherit_mv) { + /* 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 || ctx->frame_type == FRAMETYPE_INTRA1) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ @@ -528,15 +557,16 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, if (!mb->type) { mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ } else { - if (band->inherit_mv && 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; - } + if (band->inherit_mv) { + 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, diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index 52dddd2ad9..6f6de8706d 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -74,7 +74,7 @@ static int decode_gop_header(IVI45DecContext *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 */ @@ -85,7 +85,7 @@ static int decode_gop_header(IVI45DecContext *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); @@ -98,8 +98,8 @@ static int decode_gop_header(IVI45DecContext *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; @@ -113,11 +113,11 @@ static int decode_gop_header(IVI45DecContext *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; @@ -146,51 +146,54 @@ static int decode_gop_header(IVI45DecContext *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->transform_size= 8; + 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->transform_size= 8; + 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->transform_size= 8; + 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->transform_size= 8; + 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->transform_size= 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->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; @@ -216,7 +219,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (get_bits(&ctx->gb, 2)) { av_log(avctx, AV_LOG_ERROR, "End marker missing!\n"); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -246,17 +249,17 @@ static int decode_gop_header(IVI45DecContext *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)) @@ -305,25 +308,27 @@ static inline void skip_hdr_extension(GetBitContext *gb) */ 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) { - ctx->gop_invalid = 1; - if (decode_gop_header(ctx, avctx)) { + if ((ret = decode_gop_header(ctx, avctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n"); - return AVERROR_INVALIDDATA; + ctx->gop_invalid = 1; + return ret; } ctx->gop_invalid = 0; } @@ -346,8 +351,10 @@ static int decode_pic_hdr(IVI45DecContext *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! */ } @@ -369,7 +376,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) 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); @@ -393,7 +400,7 @@ static int decode_band_hdr(IVI45DecContext *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 */ @@ -405,8 +412,10 @@ static int decode_band_hdr(IVI45DecContext *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) @@ -473,7 +482,7 @@ static int decode_mb_info(IVI45DecContext *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 */ @@ -648,7 +657,7 @@ 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; diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index 44b13aa5ed..cf57059740 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -757,6 +757,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{ diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 21954ec5a4..d8b5e00a6a 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -41,6 +41,29 @@ extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tabl static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables +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. @@ -50,9 +73,10 @@ static uint16_t inv_bits(uint16_t val, int nbits) uint16_t res; if (nbits <= 8) { - res = ff_reverse[val] >> (8-nbits); + res = ff_reverse[val] >> (8 - nbits); } else - res = ((ff_reverse[val & 0xFF] << 8) + (ff_reverse[val >> 8])) >> (16-nbits); + res = ((ff_reverse[val & 0xFF] << 8) + + (ff_reverse[val >> 8])) >> (16 - nbits); return res; } @@ -85,7 +109,7 @@ static int 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]) @@ -111,10 +135,12 @@ void ff_ivi_init_static_vlc(void) for (i = 0; i < 8; i++) { ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192; ivi_mb_vlc_tabs[i].table_allocated = 8192; - ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &ivi_mb_vlc_tabs[i], 1); + ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], + &ivi_mb_vlc_tabs[i], 1); ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192; ivi_blk_vlc_tabs[i].table_allocated = 8192; - ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ivi_blk_vlc_tabs[i], 1); + ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], + &ivi_blk_vlc_tabs[i], 1); } initialized_vlcs = 1; } @@ -138,56 +164,59 @@ static void ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src) * @param[in] desc2 ptr to the 2nd descriptor to compare * @return comparison result: 0 - equal, 1 - not equal */ -static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2) +static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, + const IVIHuffDesc *desc2) { - return desc1->num_rows != desc2->num_rows - || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); + return desc1->num_rows != desc2->num_rows || + memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); } 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) ? &ivi_blk_vlc_tabs[7] - : &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); - if (!new_huff.num_rows) { - av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n"); - return AVERROR_INVALIDDATA; - } + : &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 (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { - ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); - - if (huff_tab->cust_tab.table) - ff_free_vlc(&huff_tab->cust_tab); - result = 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) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel] - : &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 (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { + ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + + if (huff_tab->cust_tab.table) + ff_free_vlc(&huff_tab->cust_tab); + result = ivi_create_huff_from_desc(&huff_tab->cust_desc, + &huff_tab->cust_tab, 0); + if (result) { + // reset faulty description + huff_tab->cust_desc.num_rows = 0; + 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) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel] + : &ivi_mb_vlc_tabs [huff_tab->tab_sel]; } return 0; @@ -216,17 +245,23 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].tiles); } av_freep(&planes[p].bands); + planes[p].num_bands = 0; } } av_cold int 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; 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; @@ -245,8 +280,10 @@ av_cold int 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) */ @@ -275,19 +312,56 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) 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; } } return 0; } -av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height) +static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile, + int p, int b, int t_height, int t_width) { - int p, b, x, y, x_tiles, y_tiles, t_width, t_height; + 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; +} + +av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, + int tile_width, int tile_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; @@ -311,44 +385,14 @@ av_cold int 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->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) { - tile->ref_mbs = ref_tile->mbs; - }else - av_log(NULL, AV_LOG_DEBUG, "Cannot use ref_tile, too few mbs\n"); - 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; } @@ -380,6 +424,117 @@ static int 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 (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, + AVCodecContext *avctx) +{ + 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) { + av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); + 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) { + av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); + 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]; + + if (!val) + av_dlog(avctx, "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; + /* 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; + } + + if(band->transform_size > band->blk_size){ + av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); + return AVERROR_INVALIDDATA; + } + + /* 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; +} /* * Decode block data: * extract huffman-coded transform coefficients from the bitstream, @@ -391,27 +546,22 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) * @param[in] tile pointer to the tile descriptor * @return result code: 0 - OK, -1 = error (corrupted blocks data) */ -static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile, - AVCodecContext *avctx) +static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, + IVITile *tile, AVCodecContext *avctx) { - int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val, - pos, is_intra, mc_type = 0, av_uninit(mv_x), av_uninit(mv_y), col_mask; - uint8_t col_flags[8]; - int32_t prev_dc, trvec[64]; - uint32_t cbp, av_uninit(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; @@ -427,7 +577,6 @@ static int 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]; @@ -448,10 +597,10 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile 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) { + 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; } } @@ -467,83 +616,26 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile } if (cbp & 1) { /* block coded ? */ - if (!band->scan) { - av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); - return AVERROR_INVALIDDATA; - } - 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(avctx, 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 >= (unsigned)num_coeffs) - break; - pos = band->scan[scan_pos]; - - if (!val) - av_dlog(avctx, "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; - } - if(band->transform_size > band->blk_size){ - av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); - return AVERROR_INVALIDDATA; - } - /* 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, avctx); + 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(&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); + 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; @@ -568,12 +660,11 @@ 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 " @@ -663,9 +754,10 @@ static int 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 { @@ -804,8 +896,16 @@ static int decode_band(IVI45DecContext *ctx, break; result = ivi_decode_blocks(&ctx->gb, band, tile, avctx); - if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); + 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; } @@ -813,7 +913,8 @@ static int decode_band(IVI45DecContext *ctx, } } - /* restore the selected rvmap table by applying its corrections in reverse order */ + /* 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]; @@ -830,7 +931,8 @@ static int decode_band(IVI45DecContext *ctx, 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 checksum mismatch! Plane %d, band %d, " + "received: %x, calculated: %x\n", band->plane, band->band_num, band->checksum, chksum); } } @@ -857,14 +959,19 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); - return -1; + 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 -1; + 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); @@ -876,24 +983,35 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for (p = 0; p < 3; p++) { for (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, &ctx->planes[p].bands[b], avctx); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p); - return -1; + return result; } } } ctx->buf_invalid[ctx->dst_buf] = 0; + } else { + if (ctx->is_scalable) + return AVERROR_INVALIDDATA; + + for (p = 0; p < 3; p++) { + if (!ctx->planes[p].bands[0].buf) + return AVERROR_INVALIDDATA; + } } if (ctx->buf_invalid[ctx->dst_buf]) return -1; //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 == AV_CODEC_ID_INDEO4 && ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { + /* 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 == AV_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) diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index fcea5f6b4f..81ab7b0fa9 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -160,9 +160,9 @@ typedef struct IVIBandDesc { 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 - int transform_size; ///< block size of the transform int32_t checksum; ///< for debug purposes int checksum_present; int bufsize; ///< band buffer size in bytes diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c index 53c4f079f8..d086de731f 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -31,6 +31,7 @@ #include "bytestream.h" #include "internal.h" #include "j2k.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #define JP2_SIG_TYPE 0x6A502020 @@ -302,6 +303,10 @@ static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c) c->log2_cblk_width = bytestream2_get_byteu(&s->g) + 2; // cblk width c->log2_cblk_height = bytestream2_get_byteu(&s->g) + 2; // cblk height + if (c->log2_cblk_width > 6 || c->log2_cblk_height > 6) { + return AVERROR_PATCHWELCOME; + } + c->cblk_style = bytestream2_get_byteu(&s->g); if (c->cblk_style != 0){ // cblk style av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); @@ -719,6 +724,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/jpeglsdec.c b/libavcodec/jpeglsdec.c index 516a82fc90..564a93f0cc 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -70,13 +70,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_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); @@ -142,6 +142,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; @@ -205,6 +207,11 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void * 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; @@ -262,7 +269,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; @@ -294,6 +301,10 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor 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 - 1); width = s->width * stride; @@ -333,11 +344,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 */ @@ -365,10 +375,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 53d8285788..128d69e1d4 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -40,6 +40,14 @@ typedef struct JvContext { static av_cold int decode_init(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; + + if (!avctx->width || !avctx->height || + (avctx->width & 7) || (avctx->height & 7)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + avctx->pix_fmt = AV_PIX_FMT_PAL8; ff_dsputil_init(&s->dsp, avctx); return 0; diff --git a/libavcodec/kbdwin.c b/libavcodec/kbdwin.c index 2722312f11..5a62e9da2b 100644 --- a/libavcodec/kbdwin.c +++ b/libavcodec/kbdwin.c @@ -16,9 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include -#include +#include "libavutil/avassert.h" +#include "libavutil/mathematics.h" #include "libavutil/attributes.h" #include "kbdwin.h" diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index edfafa0401..0a62160f26 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "bytestream.h" #include "internal.h" +#include "libavutil/common.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 @@ -47,7 +48,7 @@ typedef struct KmvcContext { int palsize; uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; - uint8_t *frm0, *frm1; + uint8_t frm0[320 * 200], frm1[320 * 200]; GetByteContext g; } KmvcContext; @@ -56,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); @@ -107,7 +108,7 @@ static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = val & 0xF; my = val >> 4; - if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) { + if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 320*197 - 4) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -132,7 +133,7 @@ static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = val & 0xF; my = val >> 4; - if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) { + if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 320*199 - 2) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -207,7 +208,7 @@ static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = (val & 0xF) - 8; my = (val >> 4) - 8; - if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) { + if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 320*197 - 4) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -232,7 +233,7 @@ static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = (val & 0xF) - 8; my = (val >> 4) - 8; - if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) { + if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 320*199 - 2) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -386,8 +387,6 @@ static av_cold int decode_init(AVCodecContext * avctx) return AVERROR_INVALIDDATA; } - c->frm0 = av_mallocz(320 * 200); - c->frm1 = av_mallocz(320 * 200); c->cur = c->frm0; c->prev = c->frm1; @@ -423,30 +422,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 = AV_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 486e326a0f..e1fa808e34 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -53,6 +53,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; @@ -567,13 +568,12 @@ static int lag_decode_frame(AVCodecContext *avctx, offs[1] = offset_gu; offs[2] = offset_ry; + l->rgb_stride = FFALIGN(avctx->width, 16); + av_fast_malloc(&l->rgb_planes, &l->rgb_planes_allocated, + l->rgb_stride * avctx->height * planes + 1); if (!l->rgb_planes) { - l->rgb_stride = FFALIGN(avctx->width, 16); - l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * 4 + 16); - 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 < planes; i++) srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride; diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h index d8d38f2054..9892d11fb3 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 5708a12d3d..68930186d9 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -199,7 +199,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac case AV_CODEC_ID_MSZH: switch (c->compression) { case COMP_MSZH: - if (c->imgtype == IMGTYPE_RGB24 && len == width * height * 3) { + if (c->imgtype == IMGTYPE_RGB24 && len == width * height * 3 || + c->imgtype == IMGTYPE_YUV111 && len == width * height * 3) { ; } else if (c->flags & FLAG_MULTITHREAD) { mthread_inlen = AV_RL32(encoded); diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c index d922fdca1b..bf226af956 100644 --- a/libavcodec/libfaac.c +++ b/libavcodec/libfaac.c @@ -199,7 +199,7 @@ static int Faac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* add current frame to the queue */ if (frame) { - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c index 196fcb5a4d..06576aabae 100644 --- a/libavcodec/libfdk-aacenc.c +++ b/libavcodec/libfdk-aacenc.c @@ -334,7 +334,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, in_buf.bufElSizes = &in_buffer_element_size; /* add current frame to the queue */ - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 1447d6a10e..24ad797222 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -191,6 +191,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, MPADecodeHeader hdr; int len, ret, ch; int lame_result; + uint32_t h; if (frame) { switch (avctx->sample_fmt) { @@ -218,7 +219,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } } else { lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); + s->buffer_size - s->buffer_index); } if (lame_result < 0) { if (lame_result == -1) { @@ -237,7 +238,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* add current frame to the queue */ if (frame) { - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } @@ -246,7 +247,12 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, determine the frame size. */ if (s->buffer_index < 4) return 0; - if (avpriv_mpegaudio_decode_header(&hdr, AV_RB32(s->buffer))) { + h = AV_RB32(s->buffer); + if (ff_mpa_check_header(h) < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid mp3 header at start of buffer\n"); + return AVERROR_BUG; + } + if (avpriv_mpegaudio_decode_header(&hdr, h)) { av_log(avctx, AV_LOG_ERROR, "free format output not supported\n"); return -1; } diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index 550ef94491..0016cc6dc2 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.c @@ -50,41 +50,6 @@ static int amr_decode_fix_avctx(AVCodecContext *avctx) #include #include -/* Common code for fixed and float version*/ -typedef struct AMR_bitrates { - int rate; - enum Mode mode; -} AMR_bitrates; - -/* Match desired bitrate */ -static int get_bitrate_mode(int bitrate, void *log_ctx) -{ - /* make the correspondance between bitrate and mode */ - static const AMR_bitrates rates[] = { - { 4750, MR475 }, { 5150, MR515 }, { 5900, MR59 }, { 6700, MR67 }, - { 7400, MR74 }, { 7950, MR795 }, { 10200, MR102 }, { 12200, MR122 } - }; - int i, best = -1, min_diff = 0; - char log_buf[200]; - - for (i = 0; i < 8; i++) { - if (rates[i].rate == bitrate) - return rates[i].mode; - if (best < 0 || abs(rates[i].rate - bitrate) < min_diff) { - best = i; - min_diff = abs(rates[i].rate - bitrate); - } - } - /* no bitrate matching exactly, log a warning */ - snprintf(log_buf, sizeof(log_buf), "bitrate not supported: use one of "); - for (i = 0; i < 8; i++) - av_strlcatf(log_buf, sizeof(log_buf), "%.2fk, ", rates[i].rate / 1000.f); - av_strlcatf(log_buf, sizeof(log_buf), "using %.2fk", rates[best].rate / 1000.f); - av_log(log_ctx, AV_LOG_WARNING, "%s\n", log_buf); - - return best; -} - typedef struct AMRContext { AVClass *av_class; AVFrame frame; @@ -97,15 +62,7 @@ typedef struct AMRContext { AudioFrameQueue afq; } AMRContext; -static const AVOption options[] = { - { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRContext, enc_dtx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, - { NULL } -}; - -static const AVClass class = { - "libopencore_amrnb", av_default_item_name, options, LIBAVUTIL_VERSION_INT -}; - +#if CONFIG_LIBOPENCORE_AMRNB_DECODER static av_cold int amr_nb_decode_init(AVCodecContext *avctx) { AMRContext *s = avctx->priv_data; @@ -186,6 +143,52 @@ AVCodec ff_libopencore_amrnb_decoder = { .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"), }; +#endif /* CONFIG_LIBOPENCORE_AMRNB_DECODER */ + +#if CONFIG_LIBOPENCORE_AMRNB_ENCODER +/* Common code for fixed and float version*/ +typedef struct AMR_bitrates { + int rate; + enum Mode mode; +} AMR_bitrates; + +/* Match desired bitrate */ +static int get_bitrate_mode(int bitrate, void *log_ctx) +{ + /* make the correspondance between bitrate and mode */ + static const AMR_bitrates rates[] = { + { 4750, MR475 }, { 5150, MR515 }, { 5900, MR59 }, { 6700, MR67 }, + { 7400, MR74 }, { 7950, MR795 }, { 10200, MR102 }, { 12200, MR122 } + }; + int i, best = -1, min_diff = 0; + char log_buf[200]; + + for (i = 0; i < 8; i++) { + if (rates[i].rate == bitrate) + return rates[i].mode; + if (best < 0 || abs(rates[i].rate - bitrate) < min_diff) { + best = i; + min_diff = abs(rates[i].rate - bitrate); + } + } + /* no bitrate matching exactly, log a warning */ + snprintf(log_buf, sizeof(log_buf), "bitrate not supported: use one of "); + for (i = 0; i < 8; i++) + av_strlcatf(log_buf, sizeof(log_buf), "%.2fk, ", rates[i].rate / 1000.f); + av_strlcatf(log_buf, sizeof(log_buf), "using %.2fk", rates[best].rate / 1000.f); + av_log(log_ctx, AV_LOG_WARNING, "%s\n", log_buf); + + return best; +} + +static const AVOption options[] = { + { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRContext, enc_dtx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, + { NULL } +}; + +static const AVClass class = { + "libopencore_amrnb", av_default_item_name, options, LIBAVUTIL_VERSION_INT +}; static av_cold int amr_nb_encode_init(AVCodecContext *avctx) { @@ -261,7 +264,7 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (frame->nb_samples < avctx->frame_size - avctx->delay) s->enc_last_frame = -1; } - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) { + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) { av_freep(&flush_buf); return ret; } @@ -304,11 +307,12 @@ AVCodec ff_libopencore_amrnb_encoder = { .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"), .priv_class = &class, }; +#endif /* CONFIG_LIBOPENCORE_AMRNB_ENCODER */ -#endif +#endif /* CONFIG_LIBOPENCORE_AMRNB */ /* -----------AMR wideband ------------*/ -#if CONFIG_LIBOPENCORE_AMRWB +#if CONFIG_LIBOPENCORE_AMRWB_DECODER #include #include @@ -392,4 +396,4 @@ AVCodec ff_libopencore_amrwb_decoder = { .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"), }; -#endif /* CONFIG_LIBOPENCORE_AMRWB */ +#endif /* CONFIG_LIBOPENCORE_AMRWB_DECODER */ diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index d198798929..b34bd836ac 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -375,7 +375,7 @@ static const AVOption libopus_options[] = { { "voip", "Favor improved speech intelligibility", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP }, 0, 0, FLAGS, "application" }, { "audio", "Favor faithfulness to the input", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO }, 0, 0, FLAGS, "application" }, { "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" }, - { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 10.0 }, 2.5, 60.0, FLAGS }, + { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 60.0, FLAGS }, { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, { "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" }, { "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" }, diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c index 7dfc6d333c..23ebe72dad 100644 --- a/libavcodec/libspeexenc.c +++ b/libavcodec/libspeexenc.c @@ -288,7 +288,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, speex_encode_stereo_int(samples, s->header.frame_size, &s->bits); speex_encode_int(s->enc_state, samples, &s->bits); s->pkt_frame_count++; - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } else { /* handle end-of-stream */ diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c index a09c74c72d..1414aadb64 100644 --- a/libavcodec/libvo-aacenc.c +++ b/libavcodec/libvo-aacenc.c @@ -157,7 +157,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, samples = (VO_PBYTE)frame->data[0]; } /* add current frame to the queue */ - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c index c81375c8ef..5424f8bf45 100644 --- a/libavcodec/libvorbisenc.c +++ b/libavcodec/libvorbisenc.c @@ -305,7 +305,7 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); return vorbis_error_to_averror(ret); } - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } else { if (!s->eof) @@ -362,7 +362,8 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, avctx->delay = duration; av_assert0(!s->afq.remaining_delay); s->afq.frames->duration += duration; - s->afq.frames->pts -= duration; + if (s->afq.frames->pts != AV_NOPTS_VALUE) + s->afq.frames->pts -= duration; s->afq.remaining_samples += duration; } ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration); diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 8765e56d02..3e7592edef 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -174,7 +174,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, 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); } @@ -335,7 +335,7 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.rc.f_rf_constant_max = x4->crf_max; } - if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy && + if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy > 0 && (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) { x4->params.rc.f_vbv_buffer_init = (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size; @@ -695,6 +695,7 @@ static const AVCodecDefault x264_defaults[] = { { "threads", AV_STRINGIFY(X264_THREADS_AUTO) }, { "thread_type", "0" }, { "flags", "+cgop" }, + { "rc_init_occupancy","-1" }, { NULL }, }; diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index d3c292123e..0ab4985c10 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -57,6 +57,13 @@ static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt, max_pkt_size += mb_width * mb_height * 3 * 4 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]; } + + if (!s->edge_emu_buffer && + (ret = ff_mpv_frame_size_alloc(s, pict->linesize[0])) < 0) { + av_log(avctx, AV_LOG_ERROR, "failed to allocate context scratch buffers.\n"); + return ret; + } + if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0) return ret; diff --git a/libavcodec/loco.c b/libavcodec/loco.c index b437aaa214..f53e11cea3 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -181,7 +181,7 @@ static int decode_frame(AVCodecContext *avctx, p->key_frame = 1; #define ADVANCE_BY_DECODED do { \ - if (decoded < 0) goto stop; \ + if (decoded < 0 || decoded >= buf_size) goto buf_too_small; \ buf += decoded; buf_size -= decoded; \ } while(0) switch(l->mode) { @@ -215,7 +215,8 @@ static int decode_frame(AVCodecContext *avctx, decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); break; - case LOCO_CRGBA: case LOCO_RGBA: + case LOCO_CRGBA: + case LOCO_RGBA: decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 4); ADVANCE_BY_DECODED; @@ -229,15 +230,18 @@ static int decode_frame(AVCodecContext *avctx, -p->linesize[0], buf, buf_size, 4); break; } -stop: *got_frame = 1; *(AVFrame*)data = l->pic; return buf_size < 0 ? -1 : avpkt->size - buf_size; +buf_too_small: + av_log(avctx, AV_LOG_ERROR, "Input data too small.\n"); + return AVERROR(EINVAL); } -static av_cold int decode_init(AVCodecContext *avctx){ +static av_cold int decode_init(AVCodecContext *avctx) +{ LOCOContext * const l = avctx->priv_data; int version; diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c index 43e3e055c2..6832c122a2 100644 --- a/libavcodec/lzw.c +++ b/libavcodec/lzw.c @@ -28,6 +28,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #include "lzw.h" #include "libavutil/mem.h" @@ -43,7 +44,7 @@ static const uint16_t mask[17] = }; struct LZWState { - const uint8_t *pbuf, *ebuf; + GetByteContext gb; int bbits; unsigned int bbuf; @@ -73,9 +74,9 @@ static int lzw_get_code(struct LZWState * s) if(s->mode == FF_LZW_GIF) { while (s->bbits < s->cursize) { if (!s->bs) { - s->bs = *s->pbuf++; + s->bs = bytestream2_get_byte(&s->gb); } - s->bbuf |= (*s->pbuf++) << s->bbits; + s->bbuf |= bytestream2_get_byte(&s->gb) << s->bbits; s->bbits += 8; s->bs--; } @@ -83,7 +84,7 @@ static int lzw_get_code(struct LZWState * s) s->bbuf >>= s->cursize; } else { // TIFF while (s->bbits < s->cursize) { - s->bbuf = (s->bbuf << 8) | (*s->pbuf++); + s->bbuf = (s->bbuf << 8) | bytestream2_get_byte(&s->gb); s->bbits += 8; } c = s->bbuf >> (s->bbits - s->cursize); @@ -97,17 +98,12 @@ void ff_lzw_decode_tail(LZWState *p) struct LZWState *s = (struct LZWState *)p; if(s->mode == FF_LZW_GIF) { - while (s->bs > 0) { - if (s->bs >= s->ebuf - s->pbuf) { - s->pbuf = s->ebuf; - break; - } else { - s->pbuf += s->bs; - s->bs = *s->pbuf++; - } + while (s->bs > 0 && bytestream2_get_bytes_left(&s->gb)) { + bytestream2_skip(&s->gb, s->bs); + s->bs = bytestream2_get_byte(&s->gb); } }else - s->pbuf= s->ebuf; + bytestream2_skip(&s->gb, bytestream2_get_bytes_left(&s->gb)); } av_cold void ff_lzw_decode_open(LZWState **p) @@ -135,8 +131,7 @@ int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, if(csize < 1 || csize >= LZW_MAXBITS) return -1; /* read buffer */ - s->pbuf = buf; - s->ebuf = s->pbuf + buf_size; + bytestream2_init(&s->gb, buf, buf_size); s->bbuf = 0; s->bbits = 0; s->bs = 0; @@ -186,10 +181,6 @@ int ff_lzw_decode(LZWState *p, uint8_t *buf, int len){ if ((--l) == 0) goto the_end; } - if (s->ebuf < s->pbuf) { - av_log(NULL, AV_LOG_ERROR, "lzw overread\n"); - goto the_end; - } c = lzw_get_code(s); if (c == s->end_code) { break; diff --git a/libavcodec/mace.c b/libavcodec/mace.c index d2a04114f4..bc63656376 100644 --- a/libavcodec/mace.c +++ b/libavcodec/mace.c @@ -229,8 +229,8 @@ static av_cold int mace_decode_init(AVCodecContext * avctx) { MACEContext *ctx = avctx->priv_data; - if (avctx->channels > 2 || avctx->channels <= 0) - return -1; + if (avctx->channels > 2 || avctx->channels < 1) + return AVERROR(EINVAL); avctx->sample_fmt = AV_SAMPLE_FMT_S16P; avcodec_get_frame_defaults(&ctx->frame); diff --git a/libavcodec/mips/acelp_filters_mips.c b/libavcodec/mips/acelp_filters_mips.c index 1e0845c3b4..9a6fdae086 100644 --- a/libavcodec/mips/acelp_filters_mips.c +++ b/libavcodec/mips/acelp_filters_mips.c @@ -89,7 +89,7 @@ static void ff_acelp_interpolatef_mips(float *out, const float *in, "addu %[p_filter_coeffs_m], %[p_filter_coeffs_m], %[prec] \n\t" "madd.s %[v],%[v],%[in_val_m], %[fc_val_m] \n\t" - : [v] "=&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m), + : [v] "+&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m), [p_filter_coeffs_p] "+r" (p_filter_coeffs_p), [in_val_p] "=&f" (in_val_p), [in_val_m] "=&f" (in_val_m), [fc_val_p] "=&f" (fc_val_p), [fc_val_m] "=&f" (fc_val_m), diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index feb2f897a5..d021e8ffda 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -211,7 +211,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { - int len, nb_components, i, width, height, pix_fmt_id; + int len, nb_components, i, width, height, bits, pix_fmt_id; int h_count[MAX_COMPONENTS]; int v_count[MAX_COMPONENTS]; @@ -220,14 +220,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* 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; } @@ -254,11 +254,12 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return -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"); + av_log(s->avctx, AV_LOG_ERROR, + "nb_components changing in interlaced picture\n"); return AVERROR_INVALIDDATA; } } - if (s->ls && !(s->bits <= 8 || nb_components == 1)) { + if (s->ls && !(bits <= 8 || nb_components == 1)) { av_log_missing_feature(s->avctx, "For JPEG-LS anything except <= 8 bits/component" " or 16-bit gray", 0); @@ -279,15 +280,18 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->h_max = h_count[i]; if (v_count[i] > s->v_max) s->v_max = v_count[i]; - if (!h_count[i] || !v_count[i]) { - av_log(s->avctx, AV_LOG_ERROR, "h/v_count is 0\n"); - return -1; - } s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) { av_log(s->avctx, AV_LOG_ERROR, "quant_index is invalid\n"); return AVERROR_INVALIDDATA; } + if (!h_count[i] || !v_count[i]) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid sampling factor in component %d %d:%d\n", + i, h_count[i], v_count[i]); + return AVERROR_INVALIDDATA; + } + av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, h_count[i], v_count[i], s->component_id[i], s->quant_index[i]); @@ -303,12 +307,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* if different size, realloc/alloc picture */ if ( width != s->width || height != s->height + || bits != s->bits || memcmp(s->h_count, h_count, sizeof(h_count[0])*nb_components) || memcmp(s->v_count, v_count, sizeof(v_count[0])*nb_components)) { av_freep(&s->qscale_table); s->width = width; s->height = height; + s->bits = bits; memcpy(s->h_count, h_count, sizeof(h_count)); memcpy(s->v_count, v_count, sizeof(v_count)); s->interlaced = 0; @@ -433,9 +439,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 = AV_PIX_FMT_RGB24; - else if (s->bits <= 8) + } else if (s->nb_components != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of components %d\n", s->nb_components); + return AVERROR_PATCHWELCOME; + } else if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; else s->avctx->pix_fmt = AV_PIX_FMT_GRAY16; @@ -740,7 +749,9 @@ static void handle_rstn(MJpegDecodeContext *s, int nb_components) i = 8 + ((-get_bits_count(&s->gb)) & 7); /* skip RSTn */ - if (s->restart_count == 0 && show_bits(&s->gb, i) == (1 << i) - 1) { + if (s->restart_count == 0) { + if( show_bits(&s->gb, i) == (1 << i) - 1 + || show_bits(&s->gb, i) == 0xFF) { int pos = get_bits_count(&s->gb); align_get_bits(&s->gb); while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF) @@ -750,6 +761,7 @@ static void handle_rstn(MJpegDecodeContext *s, int nb_components) s->last_dc[i] = 1024; } else skip_bits_long(&s->gb, pos - get_bits_count(&s->gb)); + } } } } @@ -764,6 +776,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, @@ -842,17 +860,16 @@ 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; point_transform += bits - s->bits; - av_assert0(nb_components==1 || nb_components==3); + av_assert0(nb_components>=1 && nb_components<=3); for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { @@ -1062,12 +1079,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], @@ -1076,7 +1098,9 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, "error y=%d x=%d\n", mb_y, mb_x); return AVERROR_INVALIDDATA; } - s->dsp.idct_put(ptr, linesize[c], s->block); + if (ptr) { + s->dsp.idct_put(ptr, linesize[c], s->block); + } } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + @@ -1121,13 +1145,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 (se > 63) { - av_log(s->avctx, AV_LOG_ERROR, "SE %d is too large\n", se); + av_assert0(ss>=0 && Ah>=0 && Al>=0); + if (se < ss || se > 63) { + av_log(s->avctx, AV_LOG_ERROR, "SS/SE %d/%d is invalid\n", ss, se); 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]; } @@ -1284,7 +1309,9 @@ next_field: if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0) return ret; } else { - if ((ret = ljpeg_decode_yuv_scan(s, predictor, point_transform)) < 0) + if ((ret = ljpeg_decode_yuv_scan(s, predictor, + point_transform, + nb_components)) < 0) return ret; } } @@ -1419,6 +1446,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"); @@ -1428,17 +1457,27 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) skip_bits(&s->gb, 16); /* unknown 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; } @@ -1581,8 +1620,6 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, int t = 0, b = 0; PutBitContext pb; - s->cur_scan++; - /* find marker */ while (src + t < buf_end) { uint8_t x = src[t++]; @@ -1604,6 +1641,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--; } @@ -1630,6 +1671,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; const uint8_t *unescaped_buf_ptr; + int hshift, vshift; int unescaped_buf_size; int start_code; int i, index; @@ -1645,16 +1687,21 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, &unescaped_buf_size); /* EOF */ if (start_code < 0) { - goto the_end; - } else if (unescaped_buf_size > (1U<<28)) { - av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", + break; + } else if (unescaped_buf_size > INT_MAX / 8) { + av_log(avctx, AV_LOG_ERROR, + "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", start_code, unescaped_buf_size, 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); - init_get_bits(&s->gb, unescaped_buf_ptr, unescaped_buf_size * 8); + ret = init_get_bits(&s->gb, unescaped_buf_ptr, + unescaped_buf_size * 8); + + if (ret < 0) + return ret; s->start_code = start_code; if (s->avctx->debug & FF_DEBUG_STARTCODE) @@ -1672,6 +1719,13 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, mjpeg_decode_com(s); ret = -1; + + 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; @@ -1755,6 +1809,7 @@ eoi_parser: goto the_end; case SOS: + s->cur_scan++; if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) goto fail; @@ -1784,7 +1839,7 @@ eoi_parser: (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); } } - if (s->got_picture) { + if (s->got_picture && s->cur_scan) { av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n"); goto eoi_parser; } @@ -1808,6 +1863,9 @@ the_end: } if (s->upscale_v) { uint8_t *dst = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(s->height - 1) * s->linesize[s->upscale_v]]; + int w; + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); + w = s->width >> hshift; av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P || avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ422P || @@ -1816,16 +1874,16 @@ the_end: uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[i / 2 * s->linesize[s->upscale_v]]; uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(i + 1) / 2 * s->linesize[s->upscale_v]]; if (src1 == src2) { - memcpy(dst, src1, s->width); + memcpy(dst, src1, w); } else { - for (index = 0; index < s->width; index++) + for (index = 0; index < w; index++) dst[index] = (src1[index] + src2[index]) >> 1; } dst -= s->linesize[s->upscale_v]; } } if (s->flipped && (s->avctx->flags & CODEC_FLAG_EMU_EDGE)) { - int hshift, vshift, j; + int j; avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); for (index=0; index<4; index++) { uint8_t *dst = s->picture_ptr->data[index]; diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c index f1c0a0d1e8..b2fd6007d6 100644 --- a/libavcodec/mlp_parser.c +++ b/libavcodec/mlp_parser.c @@ -126,7 +126,7 @@ uint64_t ff_truehd_layout(int chanmap) int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) { - int ratebits; + int ratebits, channel_arrangement; uint16_t checksum; av_assert1(get_bits_count(gb) == 0); @@ -157,7 +157,10 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) skip_bits(gb, 11); - mh->channels_mlp = get_bits(gb, 5); + mh->channel_arrangement= + channel_arrangement = get_bits(gb, 5); + mh->channels_mlp = mlp_channels[channel_arrangement]; + mh->channel_layout_mlp = ff_mlp_layout[channel_arrangement]; } else if (mh->stream_type == 0xba) { mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? mh->group2_bits = 0; @@ -168,11 +171,16 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) skip_bits(gb, 8); - mh->channels_thd_stream1 = get_bits(gb, 5); + mh->channel_arrangement= + channel_arrangement = get_bits(gb, 5); + mh->channels_thd_stream1 = truehd_channels(channel_arrangement); + mh->channel_layout_thd_stream1 = ff_truehd_layout(channel_arrangement); skip_bits(gb, 2); - mh->channels_thd_stream2 = get_bits(gb, 13); + channel_arrangement = get_bits(gb, 13); + mh->channels_thd_stream2 = truehd_channels(channel_arrangement); + mh->channel_layout_thd_stream2 = ff_truehd_layout(channel_arrangement); } else return AVERROR_INVALIDDATA; @@ -322,16 +330,16 @@ static int mlp_parse(AVCodecParserContext *s, if(!avctx->channels || !avctx->channel_layout) { if (mh.stream_type == 0xbb) { /* MLP stream */ - avctx->channels = mlp_channels[mh.channels_mlp]; - avctx->channel_layout = ff_mlp_layout[mh.channels_mlp]; + avctx->channels = mh.channels_mlp; + avctx->channel_layout = mh.channel_layout_mlp; } else { /* mh.stream_type == 0xba */ /* TrueHD stream */ if (mh.channels_thd_stream2) { - avctx->channels = truehd_channels(mh.channels_thd_stream2); - avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2); + avctx->channels = mh.channels_thd_stream2; + avctx->channel_layout = mh.channel_layout_thd_stream2; } else { - avctx->channels = truehd_channels(mh.channels_thd_stream1); - avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1); + avctx->channels = mh.channels_thd_stream1; + avctx->channel_layout = mh.channel_layout_thd_stream1; } } } diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h index 6aafed5086..4175e6c8cd 100644 --- a/libavcodec/mlp_parser.h +++ b/libavcodec/mlp_parser.h @@ -39,9 +39,13 @@ typedef struct MLPHeaderInfo int group1_samplerate; ///< Sample rate of first substream int group2_samplerate; ///< Sample rate of second substream (MLP only) - int channels_mlp; ///< Channel arrangement for MLP streams - int channels_thd_stream1; ///< Channel arrangement for substream 1 of TrueHD streams (5.1) - int channels_thd_stream2; ///< Channel arrangement for substream 2 of TrueHD streams (7.1) + int channel_arrangement; + int channels_mlp; ///< Channel count for MLP streams + int channels_thd_stream1; ///< Channel count for substream 1 of TrueHD streams ("6-channel presentation") + int channels_thd_stream2; ///< Channel count for substream 2 of TrueHD streams ("8-channel presentation") + uint64_t channel_layout_mlp; ///< Channel layout for MLP streams + uint64_t channel_layout_thd_stream1; ///< Channel layout for substream 1 of TrueHD streams ("6-channel presentation") + uint64_t channel_layout_thd_stream2; ///< Channel layout for substream 2 of TrueHD streams ("8-channel presentation") int access_unit_size; ///< Number of samples per coded frame int access_unit_size_pow2; ///< Next power of two above number of samples per frame diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index c7de13c15c..6b9b649993 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "libavutil/intreadwrite.h" +#include "libavutil/channel_layout.h" #include "get_bits.h" #include "internal.h" #include "libavutil/crc.h" @@ -56,6 +57,8 @@ typedef struct SubStream { uint8_t max_matrix_channel; /// For each channel output by the matrix, the output channel to map it to uint8_t ch_assign[MAX_CHANNELS]; + /// The channel layout for this substream + uint64_t ch_layout; /// Channel coding parameters for channels in the substream ChannelParams channel_params[MAX_CHANNELS]; @@ -149,6 +152,36 @@ typedef struct MLPDecodeContext { MLPDSPContext dsp; } MLPDecodeContext; +static const uint64_t thd_channel_order[] = { + AV_CH_FRONT_LEFT, AV_CH_FRONT_RIGHT, // LR + AV_CH_FRONT_CENTER, // C + AV_CH_LOW_FREQUENCY, // LFE + AV_CH_SIDE_LEFT, AV_CH_SIDE_RIGHT, // LRs + AV_CH_TOP_FRONT_LEFT, AV_CH_TOP_FRONT_RIGHT, // LRvh + AV_CH_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER, // LRc + AV_CH_BACK_LEFT, AV_CH_BACK_RIGHT, // LRrs + AV_CH_BACK_CENTER, // Cs + AV_CH_TOP_CENTER, // Ts + AV_CH_SURROUND_DIRECT_LEFT, AV_CH_SURROUND_DIRECT_RIGHT, // LRsd + AV_CH_WIDE_LEFT, AV_CH_WIDE_RIGHT, // LRw + AV_CH_TOP_FRONT_CENTER, // Cvh + AV_CH_LOW_FREQUENCY_2, // LFE2 +}; + +static uint64_t thd_channel_layout_extract_channel(uint64_t channel_layout, + int index) +{ + int i; + + if (av_get_channel_layout_nb_channels(channel_layout) <= index) + return 0; + + for (i = 0; i < FF_ARRAY_ELEMS(thd_channel_order); i++) + if (channel_layout & thd_channel_order[i] && !index--) + return thd_channel_order[i]; + return 0; +} + static VLC huff_vlc[3]; /** Initialize static data, constant between all invocations of the codec. */ @@ -328,31 +361,32 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) for (substr = 0; substr < MAX_SUBSTREAMS; substr++) m->substream[substr].restart_seen = 0; - if (mh.stream_type == 0xbb) { - /* MLP stream */ - m->avctx->channel_layout = ff_mlp_layout[mh.channels_mlp]; - } else { /* mh.stream_type == 0xba */ - /* TrueHD stream */ - if (mh.channels_thd_stream2) { - m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2); - } else { - m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1); - } - if (m->avctx->channels<=2 && m->avctx->channel_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) { + /* Set the layout for each substream. When there's more than one, the first + * substream is Stereo. Subsequent substreams' layouts are indicated in the + * major sync. */ + if (m->avctx->codec_id == AV_CODEC_ID_MLP) { + if ((substr = (mh.num_substreams > 1))) + m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO; + m->substream[substr].ch_layout = mh.channel_layout_mlp; + } else { + if ((substr = (mh.num_substreams > 1))) + m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO; + if (mh.num_substreams > 2) + if (mh.channel_layout_thd_stream2) + m->substream[2].ch_layout = mh.channel_layout_thd_stream2; + else + m->substream[2].ch_layout = mh.channel_layout_thd_stream1; + m->substream[substr].ch_layout = mh.channel_layout_thd_stream1; + + if (m->avctx->channels<=2 && m->substream[substr].ch_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) { av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n"); m->max_decoded_substream = 0; if (m->avctx->channels==2) m->avctx->channel_layout = AV_CH_LAYOUT_STEREO; } - if (m->avctx->channels && - !m->avctx->request_channels && !m->avctx->request_channel_layout && - av_get_channel_layout_nb_channels(m->avctx->channel_layout) != m->avctx->channels) { - m->avctx->channel_layout = 0; - av_log_ask_for_sample(m->avctx, "Unknown channel layout."); - } } - m->needs_reordering = mh.channels_mlp >= 18 && mh.channels_mlp <= 20; + m->needs_reordering = mh.channel_arrangement >= 18 && mh.channel_arrangement <= 20; return 0; } @@ -370,10 +404,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 == AV_CODEC_ID_MLP - ? MAX_MATRIX_CHANNEL_MLP - : MAX_MATRIX_CHANNEL_TRUEHD; - int max_channel, min_channel, matrix_channel; + int min_channel, max_channel, max_matrix_channel; + const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP + ? MAX_MATRIX_CHANNEL_MLP + : MAX_MATRIX_CHANNEL_TRUEHD; sync_word = get_bits(gbp, 13); @@ -392,18 +426,18 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, skip_bits(gbp, 16); /* Output timestamp */ - min_channel = get_bits(gbp, 4); - max_channel = get_bits(gbp, 4); - 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 (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); + std_max_matrix_channel); return AVERROR_INVALIDDATA; } - if (max_channel != 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; @@ -424,13 +458,14 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - s->min_channel = min_channel; - s->max_channel = max_channel; - s->max_matrix_channel = matrix_channel; - 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", @@ -460,6 +495,12 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, for (ch = 0; ch <= s->max_matrix_channel; ch++) { int ch_assign = get_bits(gbp, 6); + if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) { + uint64_t channel = thd_channel_layout_extract_channel(s->ch_layout, + ch_assign); + ch_assign = av_get_channel_layout_channel_index(s->ch_layout, + channel); + } if (ch_assign > s->max_matrix_channel) { av_log_ask_for_sample(m->avctx, "Assignment of matrix channel %d to invalid output channel %d.\n", @@ -481,20 +522,6 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, FFSWAP(int, s->ch_assign[3], s->ch_assign[5]); } } - if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD && - (m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1 || - m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1_WIDE)) { - FFSWAP(int, s->ch_assign[4], s->ch_assign[6]); - FFSWAP(int, s->ch_assign[5], s->ch_assign[7]); - } else if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD && - (m->avctx->channel_layout == AV_CH_LAYOUT_6POINT1 || - m->avctx->channel_layout == (AV_CH_LAYOUT_6POINT1 | AV_CH_TOP_CENTER) || - m->avctx->channel_layout == (AV_CH_LAYOUT_6POINT1 | AV_CH_TOP_FRONT_CENTER))) { - int i = s->ch_assign[6]; - s->ch_assign[6] = s->ch_assign[5]; - s->ch_assign[5] = s->ch_assign[4]; - s->ch_assign[4] = i; - } checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); @@ -524,10 +551,9 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, cp->huff_lsbs = 24; } - if (substr == m->max_decoded_substream && - m->avctx->channels != s->max_matrix_channel + 1) { - m->avctx->channels = s->max_matrix_channel + 1; - m->avctx->channel_layout = 0; + if (substr == m->max_decoded_substream) { + m->avctx->channels = s->max_matrix_channel + 1; + m->avctx->channel_layout = s->ch_layout; } return 0; @@ -720,6 +746,7 @@ static int read_channel_params(MLPDecodeContext *m, unsigned int substr, if (cp->huff_lsbs > 24) { av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n"); + cp->huff_lsbs = 0; return AVERROR_INVALIDDATA; } @@ -983,6 +1010,11 @@ static int output_data(MLPDecodeContext *m, unsigned int substr, return AVERROR_INVALIDDATA; } + if (!s->blockpos) { + av_log(avctx, AV_LOG_ERROR, "No samples to output.\n"); + return AVERROR_INVALIDDATA; + } + /* get output buffer */ m->frame.nb_samples = s->blockpos; if ((ret = ff_get_buffer(avctx, &m->frame)) < 0) { diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index c61cd576e4..aa61755b1f 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -60,6 +60,13 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; + if (!avctx->width || !avctx->height || + (avctx->width & 1) || (avctx->height & 1)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + avcodec_get_frame_defaults(&s->frame); s->frame.reference = 3; @@ -104,9 +111,12 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert) if (half_horiz) run_length *=2; + if (run_length > s->avctx->width - x) + return AVERROR_INVALIDDATA; + 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; @@ -151,6 +161,8 @@ static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert) int replace_array = bytestream2_get_byte(&s->gb); for(j=0; j<8; j++) { int replace = (replace_array >> (7-j)) & 1; + if (x + half_horiz >= s->avctx->width) + return AVERROR_INVALIDDATA; if (replace) { int color = bytestream2_get_byte(&data_ptr); s->frame.data[0][y*s->frame.linesize[0] + x] = color; diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index 61a718c5a9..fbfdd9db32 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -165,6 +165,7 @@ static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) int i; i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1); + i = FFMIN(i, FF_ARRAY_ELEMS(mp->codes) - 1); return mp->codes[i].delta; } diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c index 7f1b5b830f..9b0a6c5bce 100644 --- a/libavcodec/movtextenc.c +++ b/libavcodec/movtextenc.c @@ -21,6 +21,7 @@ #include #include "avcodec.h" +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" #include "ass_split.h" @@ -87,15 +88,18 @@ static av_cold int mov_text_encode_init(AVCodecContext *avctx) static void mov_text_text_cb(void *priv, const char *text, int len) { MovTextContext *s = priv; + av_assert0(s->end >= s->ptr); av_strlcpy(s->ptr, text, FFMIN(s->end - s->ptr, len + 1)); - s->ptr += len; + s->ptr += FFMIN(s->end - s->ptr, len); } static void mov_text_new_line_cb(void *priv, int forced) { MovTextContext *s = priv; + av_assert0(s->end >= s->ptr); av_strlcpy(s->ptr, "\n", FFMIN(s->end - s->ptr, 2)); - s->ptr++; + if (s->end > s->ptr) + s->ptr++; } static const ASSCodesCallbacks mov_text_callbacks = { diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 5ca9bb8d90..baf1e55818 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -81,6 +81,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; @@ -112,6 +121,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; @@ -128,6 +138,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; @@ -139,10 +150,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; } @@ -267,6 +274,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; @@ -283,6 +291,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; @@ -348,6 +357,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); @@ -359,6 +369,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; @@ -367,10 +378,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; @@ -422,6 +429,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); @@ -433,6 +441,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; @@ -499,6 +508,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); @@ -509,6 +519,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; @@ -517,10 +528,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; @@ -540,10 +547,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; @@ -562,6 +569,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 @@ -577,8 +585,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); @@ -587,8 +596,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; @@ -602,7 +612,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; } @@ -1266,7 +1276,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) { @@ -2001,8 +2011,6 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, width = get_bits(&s->gb, 12); height = get_bits(&s->gb, 12); - if (width <= 0 || height <= 0) - return -1; s->aspect_ratio_info = get_bits(&s->gb, 4); if (s->aspect_ratio_info == 0) { av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); @@ -2312,6 +2320,11 @@ static int decode_chunks(AVCodecContext *avctx, break; case PICTURE_START_CODE: + if (s2->width <= 0 || s2->height <= 0) { + av_log(avctx, AV_LOG_ERROR, "%dx%d is invalid\n", s2->width, s2->height); + return AVERROR_INVALIDDATA; + } + if(s->tmpgexs){ s2->intra_dc_precision= 3; s2->intra_matrix[0]= 1; diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 6374a97089..f2b5c05f0d 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -145,6 +145,9 @@ static av_cold int encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && avctx->height > 2800) + avctx->thread_count = 1; + if(ff_MPV_encode_init(avctx) < 0) return -1; @@ -180,6 +183,19 @@ static av_cold int encode_init(AVCodecContext *avctx) } } + if ((avctx->width & 0xFFF) == 0 && (avctx->height & 0xFFF) == 1) { + av_log(avctx, AV_LOG_ERROR, "Width / Height is invalid for MPEG2\n"); + return AVERROR(EINVAL); + } + + if (s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) { + if ((avctx->width & 0xFFF) == 0 || (avctx->height & 0xFFF) == 0) { + av_log(avctx, AV_LOG_ERROR, "Width or Height are not allowed to be multiplies of 4096\n" + "add '-strict %d' if you want to use them anyway.\n", FF_COMPLIANCE_UNOFFICIAL); + return AVERROR(EINVAL); + } + } + s->drop_frame_timecode = s->drop_frame_timecode || !!(avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE); if (s->drop_frame_timecode) s->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME; @@ -227,8 +243,8 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) /* mpeg1 header repeated every gop */ put_header(s, SEQ_START_CODE); - put_sbits(&s->pb, 12, s->width ); - put_sbits(&s->pb, 12, s->height); + put_sbits(&s->pb, 12, s->width & 0xFFF); + put_sbits(&s->pb, 12, s->height & 0xFFF); for(i=1; i<15; i++){ float error= aspect_ratio; diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h index 97c39b6ed6..91c091205e 100644 --- a/libavcodec/mpeg4video.h +++ b/libavcodec/mpeg4video.h @@ -111,6 +111,7 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my); extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; +void ff_mpeg4_init_tables(void); #if 0 //3IV1 is quite rare and it slows things down a tiny bit #define IS_3IV1 s->codec_tag == AV_RL32("3IV1") diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index acbc525a38..fab4bda162 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -48,6 +48,33 @@ static const int mb_type_b_map[4]= { MB_TYPE_L0 | MB_TYPE_16x16, }; +av_cold void ff_mpeg4videodec_static_init(void) +{ + static int done = 0; + + if (!done) { + ff_init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); + ff_init_rl(&ff_rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); + ff_init_rl(&ff_rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); + INIT_VLC_RL(ff_mpeg4_rl_intra, 554); + INIT_VLC_RL(ff_rvlc_rl_inter, 1072); + INIT_VLC_RL(ff_rvlc_rl_intra, 1072); + INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, + &ff_mpeg4_DCtab_lum[0][1], 2, 1, + &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); + INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, + &ff_mpeg4_DCtab_chrom[0][1], 2, 1, + &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); + INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, + &ff_sprite_trajectory_tab[0][1], 4, 2, + &ff_sprite_trajectory_tab[0][0], 4, 2, 128); + INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, + &ff_mb_type_b_tab[0][1], 2, 1, + &ff_mb_type_b_tab[0][0], 2, 1, 16); + done = 1; + } +} + /** * Predict the ac. * @param n block index (0-3 are luma, 4-5 are chroma) @@ -160,7 +187,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 +203,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 +442,8 @@ int ff_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"); } @@ -2081,8 +2108,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"); } @@ -2255,32 +2282,6 @@ end: return decode_vop_header(s, gb); } -av_cold void ff_mpeg4videodec_static_init(void) { - static int done = 0; - - if (!done) { - ff_init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); - ff_init_rl(&ff_rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); - ff_init_rl(&ff_rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); - INIT_VLC_RL(ff_mpeg4_rl_intra, 554); - INIT_VLC_RL(ff_rvlc_rl_inter, 1072); - INIT_VLC_RL(ff_rvlc_rl_intra, 1072); - INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_lum[0][1], 2, 1, - &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); - INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_chrom[0][1], 2, 1, - &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); - INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, - &ff_sprite_trajectory_tab[0][1], 4, 2, - &ff_sprite_trajectory_tab[0][0], 4, 2, 128); - INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, - &ff_mb_type_b_tab[0][1], 2, 1, - &ff_mb_type_b_tab[0][0], 2, 1, 16); - done = 1; - } -} - static av_cold int decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index 5f97d711c6..408193671f 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -30,6 +30,7 @@ typedef struct MpegAudioParseContext { int frame_size; uint32_t header; int header_count; + int no_bitrate; } MpegAudioParseContext; #define MPA_HEADER_SIZE 4 @@ -77,11 +78,14 @@ static int mpegaudio_parse(AVCodecParserContext *s1, s->header_count++; s->frame_size = ret-4; - if (s->header_count > 1) { + if (s->header_count > 0) { avctx->sample_rate= sr; avctx->channels = channels; s1->duration = frame_size; - avctx->bit_rate = bit_rate; + if (s->no_bitrate || !avctx->bit_rate) { + s->no_bitrate = 1; + avctx->bit_rate += (bit_rate - avctx->bit_rate) / s->header_count; + } } break; } diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index beef38dde3..14a47eb400 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1965,7 +1965,8 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header); - if (ch + m->nb_channels > avctx->channels || s->coff[fr] + 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; diff --git a/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c index 7841b30e30..0acd46e203 100644 --- a/libavcodec/mpegaudiodecheader.c +++ b/libavcodec/mpegaudiodecheader.c @@ -25,6 +25,8 @@ */ //#define DEBUG +#include "libavutil/common.h" + #include "avcodec.h" #include "mpegaudio.h" #include "mpegaudiodata.h" @@ -46,6 +48,8 @@ int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header) s->layer = 4 - ((header >> 17) & 3); /* extract frequency */ sample_rate_index = (header >> 10) & 3; + if (sample_rate_index >= FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) + sample_rate_index = 0; sample_rate = avpriv_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); sample_rate_index += 3 * (s->lsf + mpeg25); s->sample_rate_index = sample_rate_index; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 4609b0b731..b227415dc7 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -128,9 +128,15 @@ const enum AVPixelFormat ff_pixfmt_list_420[] = { }; const enum AVPixelFormat ff_hwaccel_pixfmt_list_420[] = { +#if CONFIG_H264_DXVA2_HWACCEL AV_PIX_FMT_DXVA2_VLD, +#endif +#if CONFIG_H264_VAAPI_HWACCEL AV_PIX_FMT_VAAPI_VLD, +#endif +#if CONFIG_H264_VDA_HWACCEL AV_PIX_FMT_VDA_VLD, +#endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }; @@ -888,7 +894,9 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) s->flags2 = s->avctx->flags2; /* set chroma shifts */ - avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, + &s->chroma_x_shift, + &s->chroma_y_shift); /* convert fourcc to upper case */ s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); @@ -1026,6 +1034,9 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) { int i, err = 0; + if (!s->context_initialized) + return AVERROR(EINVAL); + if (s->slice_context_count > 1) { for (i = 0; i < s->slice_context_count; i++) { free_duplicate_context(s->thread_context[i]); @@ -1054,8 +1065,8 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) s->mb_height = (s->height + 15) / 16; if ((s->width || s->height) && - av_image_check_size(s->width, s->height, 0, s->avctx)) - return AVERROR_INVALIDDATA; + (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) + goto fail; if ((err = init_context_frame(s))) goto fail; @@ -1071,7 +1082,7 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) } for (i = 0; i < nb_slices; i++) { - if (init_duplicate_context(s->thread_context[i], s) < 0) + if ((err = init_duplicate_context(s->thread_context[i], s)) < 0) goto fail; s->thread_context[i]->start_mb_y = (s->mb_height * (i) + nb_slices / 2) / nb_slices; @@ -1460,7 +1471,11 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) return i; } s->last_picture_ptr = &s->picture[i]; + s->last_picture_ptr->f.key_frame = 0; + s->last_picture_ptr->f.reference = 3; + s->last_picture_ptr->f.pict_type = AV_PICTURE_TYPE_P; + if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) { s->last_picture_ptr = NULL; return -1; @@ -1486,6 +1501,9 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) } s->next_picture_ptr = &s->picture[i]; s->next_picture_ptr->f.key_frame = 0; + s->next_picture_ptr->f.reference = 3; + s->next_picture_ptr->f.pict_type = AV_PICTURE_TYPE_P; + if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) { s->next_picture_ptr = NULL; return -1; @@ -1653,7 +1671,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ex -= sx; f = ((ey - sy) << 16) / ex; - for(x= 0; x <= ex; x++){ + for (x = 0; x <= ex; x++) { y = (x * f) >> 16; fr = (x * f) & 0xFFFF; buf[y * stride + x] += (color * (0x10000 - fr)) >> 16; @@ -2135,7 +2153,7 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || + if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || uvsrc_y<0 || (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, linesize >> field_based, 17, 17 + field_based, @@ -2175,11 +2193,12 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy); if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { + int hc = s->chroma_y_shift ? (h+1-bottom_field)>>1 : h; uvsx = (uvsx << 2) >> lowres; uvsy = (uvsy << 2) >> lowres; - if (h >> s->chroma_y_shift) { - pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); - pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); + if (hc) { + pix_op[op_index](dest_cb, ptr_cb, uvlinesize, hc, uvsx, uvsy); + pix_op[op_index](dest_cr, ptr_cr, uvlinesize, hc, uvsx, uvsy); } } // FIXME h261 lowres loop filter diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index c0152fb863..66beb63692 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -731,7 +731,7 @@ typedef struct MpegEncContext { #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \ (pic >= old_ctx->picture && pic < old_ctx->picture+old_ctx->picture_count ?\ - &new_ctx->picture[pic - old_ctx->picture] : pic - (Picture*)old_ctx + (Picture*)new_ctx)\ + &new_ctx->picture[pic - old_ctx->picture] : (Picture*) ((uint8_t*)pic - (uint8_t*)old_ctx + (uint8_t*)new_ctx))\ : NULL) /* mpegvideo_enc common options */ @@ -910,7 +910,7 @@ int ff_h261_get_picture_format(int width, int height); /* rv10.c */ -void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number); +int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number); int ff_rv_decode_dc(MpegEncContext *s, int n); void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 1e4c58d9ce..fe3bfd9174 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -411,18 +411,18 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) switch(avctx->codec_id) { case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: - avctx->rc_buffer_size = FFMAX(avctx->rc_max_rate, 15000000) * 112L / 15000000 * 16384; + avctx->rc_buffer_size = FFMAX(avctx->rc_max_rate, 15000000) * 112LL / 15000000 * 16384; break; case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_MSMPEG4V1: case AV_CODEC_ID_MSMPEG4V2: case AV_CODEC_ID_MSMPEG4V3: if (avctx->rc_max_rate >= 15000000) { - avctx->rc_buffer_size = 320 + (avctx->rc_max_rate - 15000000L) * (760-320) / (38400000 - 15000000); + avctx->rc_buffer_size = 320 + (avctx->rc_max_rate - 15000000LL) * (760-320) / (38400000 - 15000000); } else if(avctx->rc_max_rate >= 2000000) { - avctx->rc_buffer_size = 80 + (avctx->rc_max_rate - 2000000L) * (320- 80) / (15000000 - 2000000); + avctx->rc_buffer_size = 80 + (avctx->rc_max_rate - 2000000LL) * (320- 80) / (15000000 - 2000000); } else if(avctx->rc_max_rate >= 384000) { - avctx->rc_buffer_size = 40 + (avctx->rc_max_rate - 384000L) * ( 80- 40) / ( 2000000 - 384000); + avctx->rc_buffer_size = 40 + (avctx->rc_max_rate - 384000LL) * ( 80- 40) / ( 2000000 - 384000); } else avctx->rc_buffer_size = 40; avctx->rc_buffer_size *= 16384; @@ -3447,8 +3447,11 @@ static int encode_picture(MpegEncContext *s, int picture_number) ff_msmpeg4_encode_picture_header(s, picture_number); else if (CONFIG_MPEG4_ENCODER && s->h263_pred) ff_mpeg4_encode_picture_header(s, picture_number); - else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) - ff_rv10_encode_picture_header(s, picture_number); + else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) { + ret = ff_rv10_encode_picture_header(s, picture_number); + if (ret < 0) + return ret; + } else if (CONFIG_RV20_ENCODER && s->codec_id == AV_CODEC_ID_RV20) ff_rv20_encode_picture_header(s, picture_number); else if (CONFIG_FLV_ENCODER && s->codec_id == AV_CODEC_ID_FLV1) diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index 22381dea27..3e0211b0d6 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -215,7 +215,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) diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c index 5b7ba7fdad..847f115fba 100644 --- a/libavcodec/msrle.c +++ b/libavcodec/msrle.c @@ -35,6 +35,7 @@ #include "avcodec.h" #include "dsputil.h" #include "msrledec.h" +#include "libavutil/imgutils.h" typedef struct MsrleContext { AVCodecContext *avctx; @@ -112,7 +113,7 @@ static int msrle_decode_frame(AVCodecContext *avctx, /* FIXME how to correctly detect RLE ??? */ if (avctx->height * istride == avpkt->size) { /* assume uncompressed */ - int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8; + 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; diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c index 36a46b5978..83d7d134b1 100644 --- a/libavcodec/msrledec.c +++ b/libavcodec/msrledec.c @@ -138,14 +138,14 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, unsigned int width= FFABS(pic->linesize[0]) / (depth >> 3); output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; - output_end = pic->data[0] + avctx->height * pic->linesize[0]; + output_end = output + FFABS(pic->linesize[0]); + while (bytestream2_get_bytes_left(gb) > 0) { p1 = bytestream2_get_byteu(gb); if(p1 == 0) { //Escape code p2 = bytestream2_get_byte(gb); if(p2 == 0) { //End-of-line - output = pic->data[0] + (--line) * pic->linesize[0]; - if (line < 0) { + if (--line < 0) { if (bytestream2_get_be16(gb) == 1) { // end-of-picture return 0; } else { @@ -155,6 +155,8 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, return AVERROR_INVALIDDATA; } } + output = pic->data[0] + line * pic->linesize[0]; + output_end = output + FFABS(pic->linesize[0]); pos = 0; continue; } else if(p2 == 1) { //End-of-picture @@ -169,11 +171,11 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, return -1; } output = pic->data[0] + line * pic->linesize[0] + pos * (depth >> 3); + output_end = pic->data[0] + line * pic->linesize[0] + FFABS(pic->linesize[0]); continue; } // Copy data - if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) || - (pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { + if (output + p2 * (depth >> 3) > output_end) { bytestream2_skip(gb, 2 * (depth >> 3)); continue; } else if (bytestream2_get_bytes_left(gb) < p2 * (depth >> 3)) { @@ -203,36 +205,39 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, pos += p2; } else { //run of pixels uint8_t pix[3]; //original pixel - switch(depth){ - case 8: pix[0] = bytestream2_get_byte(gb); - break; - case 16: pix16 = bytestream2_get_le16(gb); - break; - case 24: pix[0] = bytestream2_get_byte(gb); - pix[1] = bytestream2_get_byte(gb); - pix[2] = bytestream2_get_byte(gb); - break; - 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 (output + p1 * (depth >> 3) > output_end) continue; - for(i = 0; i < p1; i++) { - switch(depth){ - case 8: *output++ = pix[0]; - break; - case 16: *(uint16_t*)output = pix16; - output += 2; - break; - case 24: *output++ = pix[0]; - *output++ = pix[1]; - *output++ = pix[2]; - break; - case 32: *(uint32_t*)output = pix32; - output += 4; - break; + + switch(depth){ + case 8: + pix[0] = bytestream2_get_byte(gb); + for(i = 0; i < p1; i++) + *output++ = pix[0]; + break; + case 16: + pix16 = bytestream2_get_le16(gb); + for(i = 0; i < p1; i++) { + *(uint16_t*)output = pix16; + output += 2; } + break; + case 24: + pix[0] = bytestream2_get_byte(gb); + pix[1] = bytestream2_get_byte(gb); + pix[2] = bytestream2_get_byte(gb); + for(i = 0; i < p1; i++) { + *output++ = pix[0]; + *output++ = pix[1]; + *output++ = pix[2]; + } + break; + case 32: + pix32 = bytestream2_get_le32(gb); + for(i = 0; i < p1; i++) { + *(uint32_t*)output = pix32; + output += 4; + } + break; } pos += p1; } diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c index e0efb4823f..2cbf2d48d7 100644 --- a/libavcodec/msvideo1enc.c +++ b/libavcodec/msvideo1enc.c @@ -58,7 +58,7 @@ enum MSV1Mode{ }; #define SKIP_PREFIX 0x8400 -#define SKIPS_MAX 0x0FFF +#define SKIPS_MAX 0x03FF #define MKRGB555(in, off) ((in[off] << 10) | (in[off + 1] << 5) | (in[off + 2])) static const int remap[16] = { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 }; diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 4317e32032..41df93c6cd 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -315,7 +315,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++) { @@ -397,7 +397,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (frame->nb_samples >= NELLY_BUF_LEN) s->last_frame = 1; } - if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } else { memset(s->buf + NELLY_BUF_LEN, 0, NELLY_SAMPLES * sizeof(*s->buf)); diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index ff11d007c4..c4cbe48b0c 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -88,7 +88,7 @@ static int get_quant(AVCodecContext *avctx, NuvContext *c, const uint8_t *buf, 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); @@ -114,6 +114,8 @@ 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) @@ -121,9 +123,10 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height, 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, @@ -154,6 +157,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int keyframe; int size_change = 0; int result; + int ret; enum { NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', @@ -165,7 +169,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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) @@ -184,7 +188,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (buf_size < 12 || buf[0] != 'V') { av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n"); - return -1; + return AVERROR_INVALIDDATA; } comptype = buf[1]; switch (comptype) { @@ -204,11 +208,14 @@ 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; @@ -227,10 +234,9 @@ retry: 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; @@ -248,7 +254,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; @@ -268,7 +274,9 @@ retry: } case NUV_RTJPEG_IN_LZO: case NUV_RTJPEG: - ff_rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); + ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); + if (ret < 0) + return ret; break; case NUV_BLACK: memset(c->pic.data[0], 0, c->width * c->height); @@ -280,7 +288,7 @@ retry: break; default: av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); - return -1; + return AVERROR_INVALIDDATA; } *picture = c->pic; @@ -291,6 +299,8 @@ retry: static av_cold int decode_init(AVCodecContext *avctx) { NuvContext *c = avctx->priv_data; + int ret; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; c->pic.data[0] = NULL; c->decomp_buf = NULL; @@ -305,8 +315,8 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_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_table.h b/libavcodec/options_table.h index 2a31fa64cc..5bc6b533e1 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -98,11 +98,10 @@ static const AVOption options[]={ {"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" }, {"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" }, {"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" }, -{"extradata_size", NULL, OFFSET(extradata_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX}, {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E}, -{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E}, -{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E}, +{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, +{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, {"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E}, {"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E}, {"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, diff --git a/libavcodec/parser.c b/libavcodec/parser.c index f7cb5cfa67..c30b43e0e5 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -235,8 +235,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; @@ -249,9 +251,11 @@ 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; if (next > -FF_INPUT_BUFFER_PADDING_SIZE) memcpy(&pc->buffer[pc->index], *buf, diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index ea6fabd47b..b2898aebe3 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -311,7 +311,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* av_get_bits_per_sample returns 0 for AV_CODEC_ID_PCM_DVD */ samples_per_block = 1; - if (AV_CODEC_ID_PCM_DVD == avctx->codec_id) { + if (avctx->codec->id == AV_CODEC_ID_PCM_DVD) { if (avctx->bits_per_coded_sample != 20 && avctx->bits_per_coded_sample != 24) { av_log(avctx, AV_LOG_ERROR, diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index bac818c586..1900b8c4bc 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -42,18 +42,20 @@ static av_cold int pcx_init(AVCodecContext *avctx) return 0; } -static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst, - unsigned int bytes_per_scanline, int compressed) +static void pcx_rle_decode(GetByteContext *gb, + uint8_t *dst, + unsigned int bytes_per_scanline, + int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { - while (i0) { run = 1; value = bytestream2_get_byte(gb); - if (value >= 0xc0) { - run = value & 0x3f; + if (value >= 0xc0 && bytestream2_get_bytes_left(gb)>0) { + run = value & 0x3f; value = bytestream2_get_byte(gb); } while (i bytestream2_get_bytes_left(&gb) / h)) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return AVERROR_INVALIDDATA; } @@ -181,7 +184,13 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } else if (nplanes == 1 && bits_per_pixel == 8) { int palstart = avpkt->size - 769; - for (y=0; ysize < 769) { + av_log(avctx, AV_LOG_ERROR, "File is too short\n"); + ret = avpkt->size; + goto end; + } + + for (y = 0; y < h; y++, ptr += stride) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); memcpy(ptr, scanline, w); } @@ -192,7 +201,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (bytestream2_get_byte(&gb) != 12) { av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); - ret = AVERROR_INVALIDDATA; + ret = avpkt->size; goto end; } diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index d0cff7bba6..699876bcd6 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -212,6 +212,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); @@ -222,11 +229,6 @@ static int parse_picture_segment(AVCodecContext *avctx, return -1; } - if (buf_size > rle_bitmap_len) { - av_log(avctx, AV_LOG_ERROR, "too much RLE data\n"); - return AVERROR_INVALIDDATA; - } - ctx->pictures[picture_id].w = width; ctx->pictures[picture_id].h = height; diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index 7c8f7e9f36..8a173af481 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -237,6 +237,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); } @@ -257,6 +259,7 @@ static int decode_frame(AVCodecContext *avctx, y--; } } +finish: *got_frame = 1; *(AVFrame*)data = s->frame; diff --git a/libavcodec/png.c b/libavcodec/png.c index a4287bd7e2..b398d91000 100644 --- a/libavcodec/png.c +++ b/libavcodec/png.c @@ -38,9 +38,7 @@ static const uint8_t ff_png_pass_xshift[NB_PASSES] = { void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size) { - if(items >= UINT_MAX / size) - return NULL; - return av_malloc(items * size); + return av_mallocz_array(items, size); } void ff_png_zfree(void *opaque, void *ptr) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 21b742c850..0809d713f1 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -189,7 +189,7 @@ void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w if(bpp >= 2) g = dst[1];\ if(bpp >= 3) b = dst[2];\ if(bpp >= 4) a = dst[3];\ - for(; i < size; i+=bpp) {\ + for(; i <= size - bpp; i+=bpp) {\ dst[i+0] = r = op(r, src[i+0], last[i+0]);\ if(bpp == 1) continue;\ dst[i+1] = g = op(g, src[i+1], last[i+1]);\ @@ -205,13 +205,9 @@ void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w else if(bpp == 2) UNROLL1(2, op)\ else if(bpp == 3) UNROLL1(3, op)\ else if(bpp == 4) UNROLL1(4, op)\ - else {\ - for (; i < size; i += bpp) {\ - int j;\ - for (j = 0; j < bpp; j++)\ - dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\ - }\ - } + for (; i < size; i++) {\ + dst[i] = op(dst[i-bpp], src[i], last[i]);\ + }\ /* NOTE: 'dst' can be equal to 'last' */ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, @@ -384,6 +380,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; } @@ -567,6 +567,12 @@ static int decode_frame(AVCodecContext *avctx, case MKTAG('I', 'H', 'D', 'R'): if (length != 13) goto fail; + + if (s->state & PNG_IDAT) { + av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n"); + goto fail; + } + s->width = bytestream2_get_be32(&s->gb); s->height = bytestream2_get_be32(&s->gb); if(av_image_check_size(s->width, s->height, 0, avctx)){ @@ -634,7 +640,7 @@ static int decode_frame(AVCodecContext *avctx, } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) && s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = AV_PIX_FMT_PAL8; - } else if (s->bit_depth == 1) { + } else if (s->bit_depth == 1 && s->bits_per_pixel == 1) { avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; } else if (s->bit_depth == 8 && s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { @@ -841,9 +847,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; diff --git a/libavcodec/pngdsp.c b/libavcodec/pngdsp.c index 1ee8b57bc9..38ee458f8d 100644 --- a/libavcodec/pngdsp.c +++ b/libavcodec/pngdsp.c @@ -30,7 +30,7 @@ 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); diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index 7ba14b2d0d..a401c78f77 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -244,12 +244,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, color_type = PNG_COLOR_TYPE_RGB; break; case AV_PIX_FMT_RGBA: - avctx->bits_per_coded_sample = 32; bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case AV_PIX_FMT_RGB24: - avctx->bits_per_coded_sample = 24; bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB; break; @@ -258,7 +256,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, color_type = PNG_COLOR_TYPE_GRAY; break; case AV_PIX_FMT_GRAY8: - avctx->bits_per_coded_sample = 0x28; bit_depth = 8; color_type = PNG_COLOR_TYPE_GRAY; break; @@ -267,12 +264,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; case AV_PIX_FMT_MONOBLACK: - avctx->bits_per_coded_sample = bit_depth = 1; color_type = PNG_COLOR_TYPE_GRAY; break; case AV_PIX_FMT_PAL8: - avctx->bits_per_coded_sample = bit_depth = 8; color_type = PNG_COLOR_TYPE_PALETTE; break; @@ -437,6 +432,23 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, static av_cold int png_enc_init(AVCodecContext *avctx){ PNGEncContext *s = avctx->priv_data; + switch(avctx->pix_fmt) { + case AV_PIX_FMT_RGBA: + avctx->bits_per_coded_sample = 32; + break; + case AV_PIX_FMT_RGB24: + avctx->bits_per_coded_sample = 24; + break; + case AV_PIX_FMT_GRAY8: + avctx->bits_per_coded_sample = 0x28; + break; + case AV_PIX_FMT_MONOBLACK: + avctx->bits_per_coded_sample = 1; + break; + case AV_PIX_FMT_PAL8: + avctx->bits_per_coded_sample = 8; + } + avcodec_get_frame_defaults(&s->picture); avctx->coded_frame= &s->picture; ff_dsputil_init(&s->dsp, avctx); diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index 13ecbb057f..e73f5a7acb 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -163,6 +163,8 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (s->maxval >= 256) { if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) { avctx->pix_fmt = AV_PIX_FMT_GRAY16BE; + if (s->maxval != 65535) + avctx->pix_fmt = AV_PIX_FMT_GRAY16; } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) { avctx->pix_fmt = AV_PIX_FMT_RGB48BE; } else { diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c index be54b48303..cc6df86996 100644 --- a/libavcodec/ppc/h264_altivec.c +++ b/libavcodec/ppc/h264_altivec.c @@ -1005,7 +1005,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/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c index 4fa2817e86..0665e3d5e7 100644 --- a/libavcodec/proresdec_lgpl.c +++ b/libavcodec/proresdec_lgpl.c @@ -164,6 +164,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; } avctx->color_primaries = buf[14]; @@ -366,7 +368,7 @@ static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, /** * Decode AC coefficients for all blocks in a slice. */ -static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out, +static inline int decode_ac_coeffs(GetBitContext *gb, DCTELEM *out, int blocks_per_slice, int plane_size_factor, const uint8_t *scan) @@ -387,15 +389,19 @@ static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out, bits_left = get_bits_left(gb); if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) - return; + return 0; run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]); + if (run < 0) + return AVERROR_INVALIDDATA; bits_left = get_bits_left(gb); if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) - return; + return AVERROR_INVALIDDATA; level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1; + if (level < 0) + return AVERROR_INVALIDDATA; pos += run + 1; if (pos >= max_coeffs) @@ -405,22 +411,24 @@ static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out, out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] = (level ^ sign) - sign; } + + return 0; } /** * Decode a slice plane (luma or chroma). */ -static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, - const uint8_t *buf, - int data_size, uint16_t *out_ptr, - int linesize, int mbs_per_slice, - int blocks_per_mb, int plane_size_factor, - const int16_t *qmat, int is_chroma) +static int decode_slice_plane(ProresContext *ctx, ProresThreadData *td, + const uint8_t *buf, + int data_size, uint16_t *out_ptr, + int linesize, int mbs_per_slice, + int blocks_per_mb, int plane_size_factor, + const int16_t *qmat, int is_chroma) { GetBitContext gb; DCTELEM *block_ptr; - int mb_num, blocks_per_slice; + int mb_num, blocks_per_slice, ret; blocks_per_slice = mbs_per_slice * blocks_per_mb; @@ -430,8 +438,10 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, decode_dc_coeffs(&gb, td->blocks, blocks_per_slice); - decode_ac_coeffs(&gb, td->blocks, blocks_per_slice, - plane_size_factor, ctx->scantable.permutated); + ret = decode_ac_coeffs(&gb, td->blocks, blocks_per_slice, + plane_size_factor, ctx->scantable.permutated); + if (ret < 0) + return ret; /* inverse quantization, inverse transform and output */ block_ptr = td->blocks; @@ -465,6 +475,7 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, } } } + return 0; } @@ -483,6 +494,7 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) int i, sf, slice_width_factor; int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size; int y_linesize, u_linesize, v_linesize; + int ret; buf = ctx->slice_data[slice_num].index; slice_data_size = ctx->slice_data[slice_num + 1].index - buf; @@ -539,28 +551,34 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) } /* decode luma plane */ - decode_slice_plane(ctx, td, buf + hdr_size, y_data_size, - (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize + - (mb_x_pos << 5)), y_linesize, - mbs_per_slice, 4, slice_width_factor + 2, - td->qmat_luma_scaled, 0); + ret = decode_slice_plane(ctx, td, buf + hdr_size, y_data_size, + (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize + + (mb_x_pos << 5)), y_linesize, + mbs_per_slice, 4, slice_width_factor + 2, + td->qmat_luma_scaled, 0); + if (ret < 0) + return ret; /* decode U chroma plane */ - decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size, - (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize + - (mb_x_pos << ctx->mb_chroma_factor)), - u_linesize, mbs_per_slice, ctx->num_chroma_blocks, - slice_width_factor + ctx->chroma_factor - 1, - td->qmat_chroma_scaled, 1); + ret = decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size, + (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize + + (mb_x_pos << ctx->mb_chroma_factor)), + u_linesize, mbs_per_slice, ctx->num_chroma_blocks, + slice_width_factor + ctx->chroma_factor - 1, + td->qmat_chroma_scaled, 1); + if (ret < 0) + return ret; /* decode V chroma plane */ - decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size, - v_data_size, - (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize + - (mb_x_pos << ctx->mb_chroma_factor)), - v_linesize, mbs_per_slice, ctx->num_chroma_blocks, - slice_width_factor + ctx->chroma_factor - 1, - td->qmat_chroma_scaled, 1); + ret = decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size, + v_data_size, + (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize + + (mb_x_pos << ctx->mb_chroma_factor)), + v_linesize, mbs_per_slice, ctx->num_chroma_blocks, + slice_width_factor + ctx->chroma_factor - 1, + td->qmat_chroma_scaled, 1); + if (ret < 0) + return ret; return 0; } diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c index 8c71ca5aea..0e79afb5ca 100644 --- a/libavcodec/proresenc_anatoliy.c +++ b/libavcodec/proresenc_anatoliy.c @@ -303,7 +303,7 @@ static int encode_slice_plane(AVCodecContext *avctx, int mb_count, } blocks_per_slice = mb_count << (2 - chroma); - init_put_bits(&pb, buf, buf_size << 3); + init_put_bits(&pb, buf, buf_size); encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat); encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat); diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index 0462c74b13..4a8a8aea06 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -455,6 +455,11 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, num_cblocks, plane_factor, qmat); total_size += sizes[i]; + if (put_bits_left(pb) < 0) { + av_log(avctx, AV_LOG_ERROR, "Serious underevaluation of" + "required buffer size"); + return AVERROR_BUFFER_TOO_SMALL; + } } return total_size; } @@ -753,9 +758,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; - pkt_size = ctx->frame_size_upper_bound + FF_MIN_BUFFER_SIZE; + pkt_size = ctx->frame_size_upper_bound; - if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + FF_MIN_BUFFER_SIZE)) < 0) return ret; orig_buf = pkt->data; @@ -831,8 +836,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream_put_byte(&buf, slice_hdr_size << 3); slice_hdr = buf; buf += slice_hdr_size - 1; - init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8); - encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice); + init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf))); + ret = encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice); + if (ret < 0) + return ret; bytestream_put_byte(&slice_hdr, q); slice_size = slice_hdr_size + sizes[ctx->num_planes - 1]; diff --git a/libavcodec/psymodel.c b/libavcodec/psymodel.c index a4a7cbb683..09dd83d315 100644 --- a/libavcodec/psymodel.c +++ b/libavcodec/psymodel.c @@ -106,7 +106,7 @@ av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *av if (!cutoff_coeff && avctx->codec_id == AV_CODEC_ID_AAC) cutoff_coeff = 2.0 * AAC_CUTOFF(avctx) / avctx->sample_rate; - if (cutoff_coeff) + if (cutoff_coeff && cutoff_coeff < 0.98) ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH, FF_FILTER_MODE_LOWPASS, FILT_ORDER, cutoff_coeff, 0.0, 0.0); diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index b55cccf200..20398302f7 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -81,8 +81,8 @@ 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; - unsigned int current_execute; int done; } ThreadContext; @@ -206,8 +206,8 @@ 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 last_execute = 0; int thread_count = avctx->thread_count; int self_id; diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index f02965e300..711f58099c 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -73,6 +73,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/qdm2.c b/libavcodec/qdm2.c index c8727c6b1c..e75aa3c95a 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -219,121 +219,154 @@ static const uint16_t qdm2_vlc_offs[] = { 0,260,566,598,894,1166,1230,1294,1678,1950,2214,2278,2310,2570,2834,3124,3448,3838, }; +static const int switchtable[23] = { + 0, 5, 1, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4 +}; + static av_cold void qdm2_init_vlc(void) { - static int vlcs_initialized = 0; static VLC_TYPE qdm2_table[3838][2]; - if (!vlcs_initialized) { + vlc_tab_level.table = &qdm2_table[qdm2_vlc_offs[0]]; + vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0]; + init_vlc(&vlc_tab_level, 8, 24, + vlc_tab_level_huffbits, 1, 1, + vlc_tab_level_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_level.table = &qdm2_table[qdm2_vlc_offs[0]]; - vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0]; - init_vlc (&vlc_tab_level, 8, 24, - vlc_tab_level_huffbits, 1, 1, - vlc_tab_level_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_diff.table = &qdm2_table[qdm2_vlc_offs[1]]; + vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1]; + init_vlc(&vlc_tab_diff, 8, 37, + vlc_tab_diff_huffbits, 1, 1, + vlc_tab_diff_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_diff.table = &qdm2_table[qdm2_vlc_offs[1]]; - vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1]; - init_vlc (&vlc_tab_diff, 8, 37, - vlc_tab_diff_huffbits, 1, 1, - vlc_tab_diff_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_run.table = &qdm2_table[qdm2_vlc_offs[2]]; + vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2]; + init_vlc(&vlc_tab_run, 5, 6, + vlc_tab_run_huffbits, 1, 1, + vlc_tab_run_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_run.table = &qdm2_table[qdm2_vlc_offs[2]]; - vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2]; - init_vlc (&vlc_tab_run, 5, 6, - vlc_tab_run_huffbits, 1, 1, - vlc_tab_run_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + fft_level_exp_alt_vlc.table = &qdm2_table[qdm2_vlc_offs[3]]; + fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] - + qdm2_vlc_offs[3]; + init_vlc(&fft_level_exp_alt_vlc, 8, 28, + fft_level_exp_alt_huffbits, 1, 1, + fft_level_exp_alt_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - fft_level_exp_alt_vlc.table = &qdm2_table[qdm2_vlc_offs[3]]; - fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] - qdm2_vlc_offs[3]; - init_vlc (&fft_level_exp_alt_vlc, 8, 28, - fft_level_exp_alt_huffbits, 1, 1, - fft_level_exp_alt_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + fft_level_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[4]]; + fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4]; + init_vlc(&fft_level_exp_vlc, 8, 20, + fft_level_exp_huffbits, 1, 1, + fft_level_exp_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + fft_stereo_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[5]]; + fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] - + qdm2_vlc_offs[5]; + init_vlc(&fft_stereo_exp_vlc, 6, 7, + fft_stereo_exp_huffbits, 1, 1, + fft_stereo_exp_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - fft_level_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[4]]; - fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4]; - init_vlc (&fft_level_exp_vlc, 8, 20, - fft_level_exp_huffbits, 1, 1, - fft_level_exp_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + fft_stereo_phase_vlc.table = &qdm2_table[qdm2_vlc_offs[6]]; + fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] - + qdm2_vlc_offs[6]; + init_vlc(&fft_stereo_phase_vlc, 6, 9, + fft_stereo_phase_huffbits, 1, 1, + fft_stereo_phase_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - fft_stereo_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[5]]; - fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] - qdm2_vlc_offs[5]; - init_vlc (&fft_stereo_exp_vlc, 6, 7, - fft_stereo_exp_huffbits, 1, 1, - fft_stereo_exp_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_tone_level_idx_hi1.table = + &qdm2_table[qdm2_vlc_offs[7]]; + vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] - + qdm2_vlc_offs[7]; + init_vlc(&vlc_tab_tone_level_idx_hi1, 8, 20, + vlc_tab_tone_level_idx_hi1_huffbits, 1, 1, + vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - fft_stereo_phase_vlc.table = &qdm2_table[qdm2_vlc_offs[6]]; - fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] - qdm2_vlc_offs[6]; - init_vlc (&fft_stereo_phase_vlc, 6, 9, - fft_stereo_phase_huffbits, 1, 1, - fft_stereo_phase_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_tone_level_idx_mid.table = + &qdm2_table[qdm2_vlc_offs[8]]; + vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] - + qdm2_vlc_offs[8]; + init_vlc(&vlc_tab_tone_level_idx_mid, 8, 24, + vlc_tab_tone_level_idx_mid_huffbits, 1, 1, + vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_tone_level_idx_hi1.table = &qdm2_table[qdm2_vlc_offs[7]]; - vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] - qdm2_vlc_offs[7]; - init_vlc (&vlc_tab_tone_level_idx_hi1, 8, 20, - vlc_tab_tone_level_idx_hi1_huffbits, 1, 1, - vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_tone_level_idx_hi2.table = + &qdm2_table[qdm2_vlc_offs[9]]; + vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] - + qdm2_vlc_offs[9]; + init_vlc(&vlc_tab_tone_level_idx_hi2, 8, 24, + vlc_tab_tone_level_idx_hi2_huffbits, 1, 1, + vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_tone_level_idx_mid.table = &qdm2_table[qdm2_vlc_offs[8]]; - vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] - qdm2_vlc_offs[8]; - init_vlc (&vlc_tab_tone_level_idx_mid, 8, 24, - vlc_tab_tone_level_idx_mid_huffbits, 1, 1, - vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_type30.table = &qdm2_table[qdm2_vlc_offs[10]]; + vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10]; + init_vlc(&vlc_tab_type30, 6, 9, + vlc_tab_type30_huffbits, 1, 1, + vlc_tab_type30_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_tone_level_idx_hi2.table = &qdm2_table[qdm2_vlc_offs[9]]; - vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] - qdm2_vlc_offs[9]; - init_vlc (&vlc_tab_tone_level_idx_hi2, 8, 24, - vlc_tab_tone_level_idx_hi2_huffbits, 1, 1, - vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_type34.table = &qdm2_table[qdm2_vlc_offs[11]]; + vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11]; + init_vlc(&vlc_tab_type34, 5, 10, + vlc_tab_type34_huffbits, 1, 1, + vlc_tab_type34_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_type30.table = &qdm2_table[qdm2_vlc_offs[10]]; - vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10]; - init_vlc (&vlc_tab_type30, 6, 9, - vlc_tab_type30_huffbits, 1, 1, - vlc_tab_type30_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_fft_tone_offset[0].table = + &qdm2_table[qdm2_vlc_offs[12]]; + vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] - + qdm2_vlc_offs[12]; + init_vlc(&vlc_tab_fft_tone_offset[0], 8, 23, + vlc_tab_fft_tone_offset_0_huffbits, 1, 1, + vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_type34.table = &qdm2_table[qdm2_vlc_offs[11]]; - vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11]; - init_vlc (&vlc_tab_type34, 5, 10, - vlc_tab_type34_huffbits, 1, 1, - vlc_tab_type34_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_fft_tone_offset[1].table = + &qdm2_table[qdm2_vlc_offs[13]]; + vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] - + qdm2_vlc_offs[13]; + init_vlc(&vlc_tab_fft_tone_offset[1], 8, 28, + vlc_tab_fft_tone_offset_1_huffbits, 1, 1, + vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_fft_tone_offset[0].table = &qdm2_table[qdm2_vlc_offs[12]]; - vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] - qdm2_vlc_offs[12]; - init_vlc (&vlc_tab_fft_tone_offset[0], 8, 23, - vlc_tab_fft_tone_offset_0_huffbits, 1, 1, - vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_fft_tone_offset[2].table = + &qdm2_table[qdm2_vlc_offs[14]]; + vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] - + qdm2_vlc_offs[14]; + init_vlc(&vlc_tab_fft_tone_offset[2], 8, 32, + vlc_tab_fft_tone_offset_2_huffbits, 1, 1, + vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_fft_tone_offset[1].table = &qdm2_table[qdm2_vlc_offs[13]]; - vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] - qdm2_vlc_offs[13]; - init_vlc (&vlc_tab_fft_tone_offset[1], 8, 28, - vlc_tab_fft_tone_offset_1_huffbits, 1, 1, - vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + vlc_tab_fft_tone_offset[3].table = + &qdm2_table[qdm2_vlc_offs[15]]; + vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] - + qdm2_vlc_offs[15]; + init_vlc(&vlc_tab_fft_tone_offset[3], 8, 35, + vlc_tab_fft_tone_offset_3_huffbits, 1, 1, + vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - vlc_tab_fft_tone_offset[2].table = &qdm2_table[qdm2_vlc_offs[14]]; - vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] - qdm2_vlc_offs[14]; - init_vlc (&vlc_tab_fft_tone_offset[2], 8, 32, - vlc_tab_fft_tone_offset_2_huffbits, 1, 1, - vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[3].table = &qdm2_table[qdm2_vlc_offs[15]]; - vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] - qdm2_vlc_offs[15]; - init_vlc (&vlc_tab_fft_tone_offset[3], 8, 35, - vlc_tab_fft_tone_offset_3_huffbits, 1, 1, - vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[4].table = &qdm2_table[qdm2_vlc_offs[16]]; - vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] - qdm2_vlc_offs[16]; - init_vlc (&vlc_tab_fft_tone_offset[4], 8, 38, - vlc_tab_fft_tone_offset_4_huffbits, 1, 1, - vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlcs_initialized=1; - } + vlc_tab_fft_tone_offset[4].table = + &qdm2_table[qdm2_vlc_offs[16]]; + vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] - + qdm2_vlc_offs[16]; + init_vlc(&vlc_tab_fft_tone_offset[4], 8, 38, + vlc_tab_fft_tone_offset_4_huffbits, 1, 1, + vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); } -static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) +static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth) { int value; @@ -341,7 +374,7 @@ static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) /* stage-2, 3 bits exponent escape sequence */ if (value-- == 0) - value = get_bits (gb, get_bits (gb, 3) + 1); + value = get_bits(gb, get_bits(gb, 3) + 1); /* stage-3, optional */ if (flag) { @@ -355,22 +388,20 @@ static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) tmp= vlc_stage3_values[value]; if ((value & ~3) > 0) - tmp += get_bits (gb, (value >> 2)); + tmp += get_bits(gb, (value >> 2)); value = tmp; } return value; } - -static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) +static int qdm2_get_se_vlc(VLC *vlc, GetBitContext *gb, int depth) { - int value = qdm2_get_vlc (gb, vlc, 0, depth); + int value = qdm2_get_vlc(gb, vlc, 0, depth); return (value & 1) ? ((value + 1) >> 1) : -(value >> 1); } - /** * QDM2 checksum * @@ -380,49 +411,50 @@ static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) * * @return 0 if checksum is OK */ -static uint16_t qdm2_packet_checksum (const uint8_t *data, int length, int value) { +static uint16_t qdm2_packet_checksum(const uint8_t *data, int length, int value) +{ int i; - for (i=0; i < length; i++) + for (i = 0; i < length; i++) value -= data[i]; return (uint16_t)(value & 0xffff); } - /** * Fill a QDM2SubPacket structure with packet type, size, and data pointer. * * @param gb bitreader context * @param sub_packet packet under analysis */ -static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet) +static void qdm2_decode_sub_packet_header(GetBitContext *gb, + QDM2SubPacket *sub_packet) { - sub_packet->type = get_bits (gb, 8); + sub_packet->type = get_bits(gb, 8); if (sub_packet->type == 0) { sub_packet->size = 0; sub_packet->data = NULL; } else { - sub_packet->size = get_bits (gb, 8); + sub_packet->size = get_bits(gb, 8); - if (sub_packet->type & 0x80) { - sub_packet->size <<= 8; - sub_packet->size |= get_bits (gb, 8); - sub_packet->type &= 0x7f; - } + if (sub_packet->type & 0x80) { + sub_packet->size <<= 8; + sub_packet->size |= get_bits(gb, 8); + sub_packet->type &= 0x7f; + } - if (sub_packet->type == 0x7f) - sub_packet->type |= (get_bits (gb, 8) << 8); + if (sub_packet->type == 0x7f) + sub_packet->type |= (get_bits(gb, 8) << 8); - sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data + // FIXME: this depends on bitreader-internal data + sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; } - av_log(NULL,AV_LOG_DEBUG,"Subpacket: type=%d size=%d start_offs=%x\n", - sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); + av_log(NULL, AV_LOG_DEBUG, "Subpacket: type=%d size=%d start_offs=%x\n", + sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); } - /** * Return node pointer to first packet of requested type in list. * @@ -430,7 +462,8 @@ static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub * @param type type of searched subpacket * @return node pointer for subpacket if found, else NULL */ -static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type) +static QDM2SubPNode *qdm2_search_subpacket_type_in_list(QDM2SubPNode *list, + int type) { while (list != NULL && list->packet != NULL) { if (list->packet->type == type) @@ -440,14 +473,13 @@ static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int return NULL; } - /** * Replace 8 elements with their average value. * Called by qdm2_decode_superblock before starting subblock decoding. * * @param q context */ -static void average_quantized_coeffs (QDM2Context *q) +static void average_quantized_coeffs(QDM2Context *q) { int i, j, n, ch, sum; @@ -464,12 +496,11 @@ static void average_quantized_coeffs (QDM2Context *q) if (sum > 0) sum--; - for (j=0; j < 8; j++) + for (j = 0; j < 8; j++) q->quantized_coeffs[ch][i][j] = sum; } } - /** * Build subband samples with noise weighted by q->tone_level. * Called by synthfilt_build_sb_samples. @@ -477,7 +508,7 @@ static void average_quantized_coeffs (QDM2Context *q) * @param q context * @param sb subband index */ -static void build_sb_samples_from_noise (QDM2Context *q, int sb) +static void build_sb_samples_from_noise(QDM2Context *q, int sb) { int ch, j; @@ -486,14 +517,16 @@ static void build_sb_samples_from_noise (QDM2Context *q, int sb) if (!q->nb_channels) return; - for (ch = 0; ch < q->nb_channels; ch++) + for (ch = 0; ch < q->nb_channels; ch++) { for (j = 0; j < 64; j++) { - q->sb_samples[ch][j * 2][sb] = SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j]; - q->sb_samples[ch][j * 2 + 1][sb] = SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j]; + q->sb_samples[ch][j * 2][sb] = + SB_DITHERING_NOISE(sb, q->noise_idx) * q->tone_level[ch][sb][j]; + q->sb_samples[ch][j * 2 + 1][sb] = + SB_DITHERING_NOISE(sb, q->noise_idx) * q->tone_level[ch][sb][j]; } + } } - /** * Called while processing data from subpackets 11 and 12. * Used after making changes to coding_method array. @@ -502,44 +535,65 @@ 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 j, k; int ch; int run, case_val; - static const int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4}; 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]) { - case 0: run = 10; case_val = 10; break; - case 1: run = 1; case_val = 16; break; - case 2: run = 5; case_val = 24; break; - case 3: run = 3; case_val = 30; break; - case 4: run = 1; case_val = 30; break; - case 5: run = 1; case_val = 8; break; - default: run = 1; case_val = 8; break; + switch (switchtable[coding_method[ch][sb][j] - 8]) { + case 0: run = 10; + case_val = 10; + break; + case 1: run = 1; + case_val = 16; + break; + case 2: run = 5; + case_val = 24; + break; + case 3: run = 3; + case_val = 30; + break; + case 4: run = 1; + case_val = 30; + break; + case 5: run = 1; + case_val = 8; + break; + default: run = 1; + case_val = 8; + break; } } - for (k = 0; k < run; k++) - if (j + k < 128) - if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) + for (k = 0; k < run; k++) { + if (j + k < 128) { + if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) { if (k > 0) { - SAMPLES_NEEDED + SAMPLES_NEEDED //not debugged, almost never used - memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t)); - memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t)); + memset(&coding_method[ch][sb][j + k], case_val, + k *sizeof(int8_t)); + memset(&coding_method[ch][sb][j + k], case_val, + 3 * sizeof(int8_t)); } + } + } + } j += run; } } + return 0; } - /** * Related to synthesis filter * Called by process_subpacket_10 @@ -547,7 +601,7 @@ static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_ * @param q context * @param flag 1 if called after getting data from subpacket 10, 0 if no subpacket 10 */ -static void fill_tone_level_array (QDM2Context *q, int flag) +static void fill_tone_level_array(QDM2Context *q, int flag) { int i, sb, ch, sb_used; int tmp, tab; @@ -619,16 +673,14 @@ static void fill_tone_level_array (QDM2Context *q, int flag) } } } - - return; } - /** * Related to synthesis filter * Called by process_subpacket_11 * c is built with data from subpacket 11 - * Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples + * Most of this function is used only if superblock_type_2_3 == 0, + * never seen it in samples. * * @param tone_level_idx * @param tone_level_idx_temp @@ -638,9 +690,12 @@ static void fill_tone_level_array (QDM2Context *q, int flag) * @param superblocktype_2_3 flag based on superblock packet type * @param cm_table_select q->cm_table_select */ -static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp, - sb_int8_array coding_method, int nb_channels, - int c, int superblocktype_2_3, int cm_table_select) +static void fill_coding_method_array(sb_int8_array tone_level_idx, + sb_int8_array tone_level_idx_temp, + sb_int8_array coding_method, + int nb_channels, + int c, int superblocktype_2_3, + int cm_table_select) { int ch, sb, j; int tmp, acc, esp_40, comp; @@ -746,15 +801,14 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra for (j = 0; j < 64; j++) coding_method[ch][sb][j] = coding_method_table[cm_table_select][sb]; } - - return; } - /** * - * Called by process_subpacket_11 to process more data from subpacket 11 with sb 0-8 - * Called by process_subpacket_12 to process data from subpacket 12 with sb 8-sb_used + * Called by process_subpacket_11 to process more data from subpacket 11 + * with sb 0-8. + * Called by process_subpacket_12 to process data from subpacket 12 with + * sb 8-sb_used. * * @param q context * @param gb bitreader context @@ -762,10 +816,11 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra * @param sb_min lower subband processed (sb_min included) * @param sb_max higher subband processed (sb_max excluded) */ -static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) +static int 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; @@ -780,8 +835,6 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le } 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) @@ -805,11 +858,16 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le 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 = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0; type34_predictor = 0.0; type34_first = 1; @@ -927,16 +985,18 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le } 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) @@ -950,16 +1010,18 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le return 0; } - /** - * Init the first element of a channel in quantized_coeffs with data from packet 10 (quantized_coeffs[ch][0]). - * This is similar to process_subpacket_9, but for a single channel and for element [0] + * Init the first element of a channel in quantized_coeffs with data + * from packet 10 (quantized_coeffs[ch][0]). + * This is similar to process_subpacket_9, but for a single channel + * and for element [0] * same VLC tables as process_subpacket_9 are used. * * @param quantized_coeffs pointer to quantized_coeffs[ch][0] * @param gb bitreader context */ -static int init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb) +static int init_quantized_coeffs_elem0(int8_t *quantized_coeffs, + GetBitContext *gb) { int i, k, run, level, diff; @@ -990,11 +1052,11 @@ static int init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext return 0; } - /** * Related to synthesis filter, process data from packet 10 * Init part of quantized_coeffs via function init_quantized_coeffs_elem0 - * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with data from packet 10 + * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with + * data from packet 10 * * @param q context * @param gb bitreader context @@ -1062,32 +1124,32 @@ static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb) * @param q context * @param node pointer to node with packet */ -static int process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) +static int process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int i, j, k, n, ch, run, level, diff; - init_get_bits(&gb, node->packet->data, node->packet->size*8); + init_get_bits(&gb, node->packet->data, node->packet->size * 8); - n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; // same as averagesomething function + n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; for (i = 1; i < n; i++) - for (ch=0; ch < q->nb_channels; ch++) { + for (ch = 0; ch < q->nb_channels; ch++) { level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2); q->quantized_coeffs[ch][i][0] = level; for (j = 0; j < (8 - 1); ) { - run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; + run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); if (j + run >= 8) return -1; for (k = 1; k <= run; k++) - q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run)); + q->quantized_coeffs[ch][i][j + k] = (level + ((k * diff) / run)); level += diff; - j += run; + j += run; } } @@ -1098,14 +1160,13 @@ static int process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) return 0; } - /** * Process subpacket 10 if not null, else * * @param q context * @param node pointer to node with packet */ -static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node) +static void process_subpacket_10(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; @@ -1118,14 +1179,13 @@ static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node) } } - /** * Process subpacket 11 * * @param q context * @param node pointer to node with packet */ -static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node) +static void process_subpacket_11(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int length = 0; @@ -1136,24 +1196,25 @@ static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node) } if (length >= 32) { - int c = get_bits (&gb, 13); + int c = get_bits(&gb, 13); if (c > 3) - fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method, - q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select); + fill_coding_method_array(q->tone_level_idx, + q->tone_level_idx_temp, q->coding_method, + q->nb_channels, 8 * c, + q->superblocktype_2_3, q->cm_table_select); } synthfilt_build_sb_samples(q, &gb, length, 0, 8); } - /** * Process subpacket 12 * * @param q context * @param node pointer to node with packet */ -static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node) +static void process_subpacket_12(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int length = 0; @@ -1172,7 +1233,7 @@ static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node) * @param q context * @param list list with synthesis filter packets (list D) */ -static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list) +static void process_synthesis_subpackets(QDM2Context *q, QDM2SubPNode *list) { QDM2SubPNode *nodes[4]; @@ -1199,13 +1260,12 @@ static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list) process_subpacket_12(q, NULL); } - -/** +/* * Decode superblock, fill packet lists. * * @param q context */ -static void qdm2_decode_super_block (QDM2Context *q) +static void qdm2_decode_super_block(QDM2Context *q) { GetBitContext gb; QDM2SubPacket header, *packet; @@ -1217,33 +1277,33 @@ static void qdm2_decode_super_block (QDM2Context *q) memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2)); q->sub_packets_B = 0; - sub_packets_D = 0; + sub_packets_D = 0; average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] - init_get_bits(&gb, q->compressed_data, q->compressed_size*8); + init_get_bits(&gb, q->compressed_data, q->compressed_size * 8); qdm2_decode_sub_packet_header(&gb, &header); if (header.type < 2 || header.type >= 8) { q->has_errors = 1; - av_log(NULL,AV_LOG_ERROR,"bad superblock type\n"); + av_log(NULL, AV_LOG_ERROR, "bad superblock type\n"); return; } q->superblocktype_2_3 = (header.type == 2 || header.type == 3); - packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); + packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); - init_get_bits(&gb, header.data, header.size*8); + init_get_bits(&gb, header.data, header.size * 8); if (header.type == 2 || header.type == 4 || header.type == 5) { - int csum = 257 * get_bits(&gb, 8); - csum += 2 * get_bits(&gb, 8); + int csum = 257 * get_bits(&gb, 8); + csum += 2 * get_bits(&gb, 8); csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum); if (csum != 0) { q->has_errors = 1; - av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n"); + av_log(NULL, AV_LOG_ERROR, "bad packet checksum\n"); return; } } @@ -1258,7 +1318,7 @@ 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)) { + if (i >= FF_ARRAY_ELEMS(q->sub_packet_list_A)) { SAMPLES_NEEDED_2("too many packet bytes"); return; } @@ -1269,8 +1329,8 @@ static void qdm2_decode_super_block (QDM2Context *q) q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; /* seek to next block */ - init_get_bits(&gb, header.data, header.size*8); - skip_bits(&gb, next_index*8); + init_get_bits(&gb, header.data, header.size * 8); + skip_bits(&gb, next_index * 8); if (next_index >= header.size) break; @@ -1279,7 +1339,7 @@ static void qdm2_decode_super_block (QDM2Context *q) /* decode subpacket */ packet = &q->sub_packets[i]; qdm2_decode_sub_packet_header(&gb, packet); - next_index = packet->size + get_bits_count(&gb) / 8; + next_index = packet->size + get_bits_count(&gb) / 8; sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2; if (packet->type == 0) @@ -1312,13 +1372,13 @@ static void qdm2_decode_super_block (QDM2Context *q) } else if (packet->type == 15) { SAMPLES_NEEDED_2("packet type 15") return; - } else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) { + } else if (packet->type >= 16 && packet->type < 48 && + !fft_subpackets[packet->type - 16]) { /* packets for FFT */ QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet); } } // Packet bytes loop -/* **************************************************************** */ if (q->sub_packet_list_D[0].packet != NULL) { process_synthesis_subpackets(q, q->sub_packet_list_D); q->do_synth_filter = 1; @@ -1327,39 +1387,38 @@ static void qdm2_decode_super_block (QDM2Context *q) process_subpacket_11(q, NULL); process_subpacket_12(q, NULL); } -/* **************************************************************** */ } - -static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet, - int offset, int duration, int channel, - int exp, int phase) +static void qdm2_fft_init_coefficient(QDM2Context *q, int sub_packet, + int offset, int duration, int channel, + int exp, int phase) { if (q->fft_coefs_min_index[duration] < 0) q->fft_coefs_min_index[duration] = q->fft_coefs_index; - q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); + q->fft_coefs[q->fft_coefs_index].sub_packet = + ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); q->fft_coefs[q->fft_coefs_index].channel = channel; - q->fft_coefs[q->fft_coefs_index].offset = offset; - q->fft_coefs[q->fft_coefs_index].exp = exp; - q->fft_coefs[q->fft_coefs_index].phase = phase; + q->fft_coefs[q->fft_coefs_index].offset = offset; + q->fft_coefs[q->fft_coefs_index].exp = exp; + q->fft_coefs[q->fft_coefs_index].phase = phase; q->fft_coefs_index++; } - -static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b) +static void qdm2_fft_decode_tones(QDM2Context *q, int duration, + GetBitContext *gb, int b) { int channel, stereo, phase, exp; - int local_int_4, local_int_8, stereo_phase, local_int_10; + int local_int_4, local_int_8, stereo_phase, local_int_10; int local_int_14, stereo_exp, local_int_20, local_int_28; int n, offset; - local_int_4 = 0; + local_int_4 = 0; local_int_28 = 0; local_int_20 = 2; - local_int_8 = (4 - duration); + local_int_8 = (4 - duration); local_int_10 = 1 << (q->group_order - duration - 1); - offset = 1; + offset = 1; while (get_bits_left(gb)>0) { if (q->superblocktype_2_3) { @@ -1371,10 +1430,10 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * } offset = 1; if (n == 0) { - local_int_4 += local_int_10; + local_int_4 += local_int_10; local_int_28 += (1 << local_int_8); } else { - local_int_4 += 8*local_int_10; + local_int_4 += 8 * local_int_10; local_int_28 += (8 << local_int_8); } } @@ -1382,7 +1441,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * } else { offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); while (offset >= (local_int_10 - 1)) { - offset += (1 - (local_int_10 - 1)); + offset += (1 - (local_int_10 - 1)); local_int_4 += local_int_10; local_int_28 += (1 << local_int_8); } @@ -1397,22 +1456,22 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * if (q->nb_channels > 1) { channel = get_bits1(gb); - stereo = get_bits1(gb); + stereo = get_bits1(gb); } else { channel = 0; - stereo = 0; + stereo = 0; } - exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); + exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; - exp = (exp < 0) ? 0 : exp; + exp = (exp < 0) ? 0 : exp; - phase = get_bits(gb, 3); - stereo_exp = 0; + phase = get_bits(gb, 3); + stereo_exp = 0; stereo_phase = 0; if (stereo) { - stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); + stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); if (stereo_phase < 0) stereo_phase += 8; @@ -1421,17 +1480,18 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * if (q->frequency_range > (local_int_14 + 1)) { int sub_packet = (local_int_20 + local_int_28); - qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase); + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, + channel, exp, phase); if (stereo) - qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase); + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, + 1 - channel, + stereo_exp, stereo_phase); } - offset++; } } - -static void qdm2_decode_fft_packets (QDM2Context *q) +static void qdm2_decode_fft_packets(QDM2Context *q) { int i, j, min, max, value, type, unknown_flag; GetBitContext gb; @@ -1441,18 +1501,18 @@ static void qdm2_decode_fft_packets (QDM2Context *q) /* reset minimum indexes for FFT coefficients */ q->fft_coefs_index = 0; - for (i=0; i < 5; i++) + for (i = 0; i < 5; i++) q->fft_coefs_min_index[i] = -1; /* process subpackets ordered by type, largest type first */ for (i = 0, max = 256; i < q->sub_packets_B; i++) { - QDM2SubPacket *packet= NULL; + QDM2SubPacket *packet = NULL; /* find subpacket with largest type less than max */ for (j = 0, min = 0; j < q->sub_packets_B; j++) { value = q->sub_packet_list_B[j].packet->type; if (value > min && value < max) { - min = value; + min = value; packet = q->sub_packet_list_B[j].packet; } } @@ -1463,11 +1523,13 @@ static void qdm2_decode_fft_packets (QDM2Context *q) if (!packet) return; - if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16])) + if (i == 0 && + (packet->type < 16 || packet->type >= 48 || + fft_subpackets[packet->type - 16])) return; /* decode FFT tones */ - init_get_bits (&gb, packet->data, packet->size*8); + init_get_bits(&gb, packet->data, packet->size * 8); if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) unknown_flag = 1; @@ -1482,13 +1544,13 @@ static void qdm2_decode_fft_packets (QDM2Context *q) if (duration >= 0 && duration < 4) qdm2_fft_decode_tones(q, duration, &gb, unknown_flag); } else if (type == 31) { - for (j=0; j < 4; j++) + for (j = 0; j < 4; j++) qdm2_fft_decode_tones(q, j, &gb, unknown_flag); } else if (type == 46) { - for (j=0; j < 6; j++) + for (j = 0; j < 6; j++) q->fft_level_exp[j] = get_bits(&gb, 6); - for (j=0; j < 4; j++) - qdm2_fft_decode_tones(q, j, &gb, unknown_flag); + for (j = 0; j < 4; j++) + qdm2_fft_decode_tones(q, j, &gb, unknown_flag); } } // Loop on B packets @@ -1503,20 +1565,19 @@ static void qdm2_decode_fft_packets (QDM2Context *q) q->fft_coefs_max_index[j] = q->fft_coefs_index; } - -static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone) +static void qdm2_fft_generate_tone(QDM2Context *q, FFTTone *tone) { - float level, f[6]; - int i; - QDM2Complex c; - const double iscale = 2.0*M_PI / 512.0; + float level, f[6]; + int i; + QDM2Complex c; + const double iscale = 2.0 * M_PI / 512.0; tone->phase += tone->phase_shift; /* calculate current level (maximum amplitude) of tone */ level = fft_tone_envelope_table[tone->duration][tone->time_index] * tone->level; - c.im = level * sin(tone->phase*iscale); - c.re = level * cos(tone->phase*iscale); + c.im = level * sin(tone->phase * iscale); + c.re = level * cos(tone->phase * iscale); /* generate FFT coefficients for tone */ if (tone->duration >= 3 || tone->cutoff >= 3) { @@ -1526,30 +1587,31 @@ static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone) tone->complex[1].re -= c.re; } else { f[1] = -tone->table[4]; - f[0] = tone->table[3] - tone->table[0]; - f[2] = 1.0 - tone->table[2] - tone->table[3]; - f[3] = tone->table[1] + tone->table[4] - 1.0; - f[4] = tone->table[0] - tone->table[1]; - f[5] = tone->table[2]; + f[0] = tone->table[3] - tone->table[0]; + f[2] = 1.0 - tone->table[2] - tone->table[3]; + f[3] = tone->table[1] + tone->table[4] - 1.0; + f[4] = tone->table[0] - tone->table[1]; + f[5] = tone->table[2]; for (i = 0; i < 2; i++) { - tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += c.re * f[i]; - tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += c.im *((tone->cutoff <= i) ? -f[i] : f[i]); + tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += + c.re * f[i]; + tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += + c.im * ((tone->cutoff <= i) ? -f[i] : f[i]); } for (i = 0; i < 4; i++) { - tone->complex[i].re += c.re * f[i+2]; - tone->complex[i].im += c.im * f[i+2]; + tone->complex[i].re += c.re * f[i + 2]; + tone->complex[i].im += c.im * f[i + 2]; } } /* copy the tone if it has not yet died out */ if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) { - memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); - q->fft_tone_end = (q->fft_tone_end + 1) % 1000; + memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); + q->fft_tone_end = (q->fft_tone_end + 1) % 1000; } } - -static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) +static void qdm2_fft_tone_synthesizer(QDM2Context *q, int sub_packet) { int i, j, ch; const double iscale = 0.25 * M_PI; @@ -1620,29 +1682,27 @@ static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) } } - -static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet) +static void qdm2_calculate_fft(QDM2Context *q, int channel, int sub_packet) { const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.5f : 1.0f; - float *out = q->output_buffer + channel; + float *out = q->output_buffer + channel; int i; q->fft.complex[channel][0].re *= 2.0f; - q->fft.complex[channel][0].im = 0.0f; + q->fft.complex[channel][0].im = 0.0f; q->rdft_ctx.rdft_calc(&q->rdft_ctx, (FFTSample *)q->fft.complex[channel]); /* add samples to output buffer */ for (i = 0; i < FFALIGN(q->fft_size, 8); i++) { out[0] += q->fft.complex[channel][i].re * gain; out[q->channels] += q->fft.complex[channel][i].im * gain; - out += 2 * q->channels; + out += 2 * q->channels; } } - /** * @param q context * @param index subpacket number */ -static void qdm2_synthesis_filter (QDM2Context *q, int index) +static void qdm2_synthesis_filter(QDM2Context *q, int index) { int i, k, ch, sb_used, sub_sampling, dither_state = 0; @@ -1651,7 +1711,7 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) for (ch = 0; ch < q->channels; ch++) for (i = 0; i < 8; i++) - for (k=sb_used; k < SBLIMIT; k++) + for (k = sb_used; k < SBLIMIT; k++) q->sb_samples[ch][(8 * index) + i][k] = 0; for (ch = 0; ch < q->nb_channels; ch++) { @@ -1659,10 +1719,10 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) for (i = 0; i < 8; i++) { ff_mpa_synth_filter_float(&q->mpadsp, - q->synth_buf[ch], &(q->synth_buf_offset[ch]), - ff_mpa_synth_window_float, &dither_state, - samples_ptr, q->nb_channels, - q->sb_samples[ch][(8 * index) + i]); + q->synth_buf[ch], &(q->synth_buf_offset[ch]), + ff_mpa_synth_window_float, &dither_state, + samples_ptr, q->nb_channels, + q->sb_samples[ch][(8 * index) + i]); samples_ptr += 32 * q->nb_channels; } } @@ -1675,29 +1735,19 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) q->output_buffer[q->channels * i + ch] += (1 << 23) * q->samples[q->nb_channels * sub_sampling * i + ch]; } - /** * Init static data (does not depend on specific file) * * @param q context */ -static av_cold void qdm2_init(QDM2Context *q) { - static int initialized = 0; - - if (initialized != 0) - return; - initialized = 1; - +static av_cold void qdm2_init_static_data(AVCodec *codec) { qdm2_init_vlc(); ff_mpa_synth_init_float(ff_mpa_synth_window_float); softclip_table_init(); rnd_table_init(); init_noise_samples(); - - av_log(NULL, AV_LOG_DEBUG, "init done\n"); } - /** * Init parameters from codec extradata */ @@ -1747,7 +1797,7 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) return -1; } - extradata = avctx->extradata; + extradata = avctx->extradata; extradata_size = avctx->extradata_size; while (extradata_size > 7) { @@ -1870,12 +1920,14 @@ 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); - qdm2_init(s); - avctx->sample_fmt = AV_SAMPLE_FMT_S16; avcodec_get_frame_defaults(&s->frame); @@ -1884,7 +1936,6 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) return 0; } - static av_cold int qdm2_decode_close(AVCodecContext *avctx) { QDM2Context *s = avctx->priv_data; @@ -1894,8 +1945,7 @@ static av_cold int qdm2_decode_close(AVCodecContext *avctx) return 0; } - -static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) +static int qdm2_decode(QDM2Context *q, const uint8_t *in, int16_t *out) { int ch, i; const int frame_size = (q->frame_size * q->channels); @@ -1957,7 +2007,6 @@ static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) return 0; } - static int qdm2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -1992,15 +2041,15 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data, return s->checksum_size; } -AVCodec ff_qdm2_decoder = -{ - .name = "qdm2", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_QDM2, - .priv_data_size = sizeof(QDM2Context), - .init = qdm2_decode_init, - .close = qdm2_decode_close, - .decode = qdm2_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"), +AVCodec ff_qdm2_decoder = { + .name = "qdm2", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_QDM2, + .priv_data_size = sizeof(QDM2Context), + .init = qdm2_decode_init, + .init_static_data = qdm2_init_static_data, + .close = qdm2_decode_close, + .decode = qdm2_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"), }; diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 105ac69600..f0cf376c02 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -163,7 +163,7 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, /* check motion vector */ if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (height - me_y - me_h < 0) || (height - me_y >= orig_height) || (filled + me_w > width) || (height - me_h < 0)) av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", me_x, me_y, me_w, me_h, filled, height); @@ -193,7 +193,7 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, filled = 0; dst -= stride; height--; - if(height < 0) + if (height < 0) break; } } @@ -209,7 +209,7 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, filled = 0; dst -= stride; height--; - if(height < 0) + if (height < 0) break; } } diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index 41fda4b3b6..c778ee3e37 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -56,22 +56,16 @@ typedef struct QtrleContext { static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change) { int rle_code; - int pixel_ptr = 0; + int pixel_ptr; int row_inc = s->frame.linesize[0]; unsigned char pi0, pi1; /* 2 8-pixel values */ unsigned char *rgb = s->frame.data[0]; int pixel_limit = s->frame.linesize[0] * s->avctx->height; int skip; - /* skip & 0x80 appears to mean 'start a new line', which can be interpreted - * as 'go to next line' during the decoding of a frame but is 'go to first - * 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 - * In the following decoding loop, row_ptr will be the position of the - * _next_ row. */ - lines_to_change++; + row_ptr -= row_inc; + pixel_ptr = row_ptr; + lines_to_change++; while (lines_to_change) { skip = bytestream2_get_byte(&s->g); rle_code = (signed char)bytestream2_get_byte(&s->g); @@ -79,8 +73,8 @@ static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change) break; if(skip & 0x80) { lines_to_change--; - pixel_ptr = row_ptr + 2 * (skip & 0x7f); row_ptr += row_inc; + pixel_ptr = row_ptr + 2 * (skip & 0x7f); } else pixel_ptr += 2 * skip; CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ @@ -126,7 +120,7 @@ static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr, while (lines_to_change--) { pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1)); - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ + CHECK_PIXEL_PTR(0); while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { @@ -181,7 +175,7 @@ static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change) while (lines_to_change--) { pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1)); - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ + CHECK_PIXEL_PTR(0); while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { @@ -231,7 +225,7 @@ static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change while (lines_to_change--) { pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ + CHECK_PIXEL_PTR(0); while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { @@ -275,7 +269,7 @@ static void qtrle_decode_24bpp(QtrleContext *s, int row_ptr, int lines_to_change while (lines_to_change--) { pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ + CHECK_PIXEL_PTR(0); while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { @@ -322,7 +316,7 @@ static void qtrle_decode_32bpp(QtrleContext *s, int row_ptr, int lines_to_change while (lines_to_change--) { pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ + CHECK_PIXEL_PTR(0); while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index 9a8ac2b2e3..b89e4b7fb0 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -536,7 +536,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, for (; i < frame->nb_samples; i++) ractx->curr_block[i] = samples[i] >> 2; - if ((ret = ff_af_queue_add(&ractx->afq, frame) < 0)) + if ((ret = ff_af_queue_add(&ractx->afq, frame)) < 0) return ret; } else ractx->last_frame = 1; diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index c90939df04..6812f9af70 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -171,9 +171,10 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) s->avctx = avctx; - if (avctx->width%16 || avctx->height%16) { - av_log_ask_for_sample(avctx, "dimensions not being a multiple of 16 are unsupported\n"); - return AVERROR_PATCHWELCOME; + 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; diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 02f1a452ae..0ce11d0970 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -942,6 +942,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"); diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index a424759953..d41675c58f 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -38,8 +38,10 @@ #include #include +#include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/common.h" #include "avcodec.h" typedef struct RpzaContext { @@ -84,7 +86,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; @@ -126,6 +128,8 @@ static void rpza_decode_stream(RpzaContext *s) } } + n_blocks = FFMIN(n_blocks, total_blocks); + switch (opcode & 0xe0) { /* Skip blocks */ @@ -140,6 +144,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++){ @@ -148,7 +153,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); } break; @@ -187,6 +191,7 @@ static void rpza_decode_stream(RpzaContext *s) 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++]; @@ -197,14 +202,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 < 16) + 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++){ @@ -218,7 +223,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); break; /* Unknown opcode */ diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c index 7797a655c1..affacf86f5 100644 --- a/libavcodec/rtjpeg.c +++ b/libavcodec/rtjpeg.c @@ -108,10 +108,13 @@ int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, const uint8_t *buf, int buf_size) { GetBitContext gb; int w = c->w / 16, h = c->h / 16; - int x, y; + int x, y, ret; uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; uint8_t *u = f->data[1], *v = f->data[2]; - init_get_bits(&gb, buf, buf_size * 8); + + if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) + return ret; + for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { #define BLOCK(quant, dst, stride) do { \ diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index e10cbbf773..f005bcc33c 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -368,6 +368,11 @@ static int rv20_decode_picture_header(RVDecContext *rv) 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{ @@ -453,12 +458,15 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) RVDecContext *rv = avctx->priv_data; MpegEncContext *s = &rv->m; 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; ff_MPV_decode_defaults(s); diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c index c4c5c53850..3bf44fb9b5 100644 --- a/libavcodec/rv10enc.c +++ b/libavcodec/rv10enc.c @@ -28,7 +28,7 @@ #include "mpegvideo.h" #include "put_bits.h" -void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) +int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) { int full_frame= 0; @@ -48,12 +48,17 @@ void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) /* if multiple packets per frame are sent, the position at which to display the macroblocks is coded here */ if(!full_frame){ + if (s->mb_width * s->mb_height >= (1U << 12)) { + av_log_missing_feature(s->avctx, "Encoding frames with 4096 macroblocks or more", 0); + return AVERROR(ENOSYS); + } put_bits(&s->pb, 6, 0); /* mb_x */ put_bits(&s->pb, 6, 0); /* mb_y */ put_bits(&s->pb, 12, s->mb_width * s->mb_height); } put_bits(&s->pb, 3, 0); /* ignored */ + return 0; } FF_MPV_GENERIC_CLASS(rv10) diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index 9d33051354..dca42b71e8 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -35,6 +35,7 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) { + AVCodecContext *avctx = r->s.avctx; int mb_bits; int w = r->s.width, h = r->s.height; int mb_size; @@ -57,6 +58,13 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn rpr = 0; } if(rpr){ + if (avctx->extradata_size < rpr * 2 + 8) { + av_log(avctx, AV_LOG_ERROR, + "Insufficient extradata - need at least %d bytes, got %d\n", + 8 + rpr * 2, avctx->extradata_size); + return AVERROR(EINVAL); + } + w = r->s.avctx->extradata[6 + rpr*2] << 2; h = r->s.avctx->extradata[7 + rpr*2] << 2; } @@ -187,7 +195,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row) for(i = !mb_x; i < 2; i++, C += 4){ int ij = i + (j >> 1); loc_lim = 0; - if(cur_cbp && (1 << ij)) + if (cur_cbp & (1 << ij)) loc_lim = cur_lim; else if(!i && left_cbp & (1 << (ij + 1))) loc_lim = left_lim; @@ -229,7 +237,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row) for(i = 0; i < 2; i++, C += 4){ int ij = i + (j >> 1); loc_lim = 0; - if(r->cbp_chroma[mb_pos] && (1 << ij)) + if (r->cbp_chroma[mb_pos] & (1 << ij)) loc_lim = cur_lim; else if(!j && top_cbp & (1 << (ij + 2))) loc_lim = top_lim; @@ -249,19 +257,18 @@ 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; } r->rpr = (avctx->extradata[1] & 7) >> 1; r->rpr = FFMIN(r->rpr + 1, 3); - if(avctx->extradata_size - 8 < (r->rpr - 1) * 2){ - av_log(avctx, AV_LOG_ERROR, "Insufficient extradata - need at least %d bytes, got %d\n", - 6 + r->rpr * 2, avctx->extradata_size); - } + r->parse_slice_header = rv30_parse_slice_header; r->decode_intra_types = rv30_decode_intra_types; r->decode_mb_info = rv30_decode_mb_info; diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index ff0ef91a5c..6c265bcf34 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -548,9 +548,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/sanm.c b/libavcodec/sanm.c index 7432fa273f..60437c0b33 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -26,6 +26,7 @@ #include "bytestream.h" #include "internal.h" #include "libavutil/bswap.h" +#include "libavutil/imgutils.h" #include "libavcodec/dsputil.h" #include "sanm_data.h" @@ -415,6 +416,11 @@ static int old_codec37(SANMVideoContext *ctx, int top, flags = bytestream2_get_byte(&ctx->gb); bytestream2_skip(&ctx->gb, 3); + if (decoded_size > ctx->height * stride - left - top * stride) { + decoded_size = ctx->height * stride - left - top * stride; + av_log(ctx->avctx, AV_LOG_WARNING, "decoded size is too large\n"); + } + ctx->rotate_code = 0; if (((seq & 1) || !(flags & 1)) && (compr && compr != 2)) @@ -638,6 +644,11 @@ static int old_codec47(SANMVideoContext *ctx, int top, decoded_size = bytestream2_get_le32(&ctx->gb); bytestream2_skip(&ctx->gb, 8); + if (decoded_size > ctx->height * stride - left - top * stride) { + decoded_size = ctx->height * stride - left - top * stride; + av_log(ctx->avctx, AV_LOG_WARNING, "decoded size is too large\n"); + } + if (skip & 1) bytestream2_skip(&ctx->gb, 0x8080); if (!seq) { @@ -715,9 +726,17 @@ static int process_frame_obj(SANMVideoContext *ctx) w = bytestream2_get_le16u(&ctx->gb); h = bytestream2_get_le16u(&ctx->gb); + if (!w || !h) { + av_log(ctx->avctx, AV_LOG_ERROR, "dimensions are invalid\n"); + return AVERROR_INVALIDDATA; + } + if (ctx->width < left + w || ctx->height < top + h) { - ctx->avctx->width = FFMAX(left + w, ctx->width); - ctx->avctx->height = FFMAX(top + h, ctx->height); + if (av_image_check_size(FFMAX(left + w, ctx->width), + FFMAX(top + h, ctx->height), 0, ctx->avctx) < 0) + return AVERROR_INVALIDDATA; + avcodec_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width), + FFMAX(top + h, ctx->height)); init_sizes(ctx, left + w, top + h); if (init_buffers(ctx)) { av_log(ctx->avctx, AV_LOG_ERROR, "error resizing buffers\n"); diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c index 555b5044af..4665c92ff6 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -28,6 +28,7 @@ typedef struct SgiState { AVFrame picture; + AVCodecContext *avctx; unsigned int width; unsigned int height; unsigned int depth; @@ -40,15 +41,16 @@ 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; + uint8_t *out_end = out_buf + len; while (out_buf < out_end) { if (bytestream2_get_bytes_left(&s->g) < 1) @@ -59,7 +61,10 @@ static int expand_rle_row(SgiState *s, uint8_t *out_buf, } /* Check for buffer overflow. */ - if(out_buf + pixelstride * (count-1) >= out_end) return -1; + if (out_end - out_buf <= pixelstride * (count - 1)) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid pixel count.\n"); + return AVERROR_INVALIDDATA; + } if (pixel & 0x80) { while (count--) { @@ -103,7 +108,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 + s->width*s->depth, + if (expand_rle_row(s, dest_row + z, s->width*s->depth, s->depth) != s->width) { return AVERROR_INVALIDDATA; } @@ -244,6 +249,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 8e66928db5..67fce3232c 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -88,7 +88,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]; @@ -113,10 +113,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; avcodec_get_frame_defaults(&s->frame); avctx->coded_frame = &s->frame; @@ -130,17 +130,20 @@ 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 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"); + 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; @@ -150,7 +153,7 @@ static int allocate_buffers(ShortenContext *s) 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; } @@ -163,7 +166,6 @@ static int allocate_buffers(ShortenContext *s) return 0; } - static inline unsigned int get_uint(ShortenContext *s, int k) { if (s->version != 0) @@ -171,7 +173,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; @@ -181,26 +182,24 @@ 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_U8: - s->avctx->sample_fmt = AV_SAMPLE_FMT_U8P; - mean = 0x80; - break; - case TYPE_S16HL: - case TYPE_S16LH: - s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown audio type\n"); - return AVERROR_PATCHWELCOME; + switch (s->internal_ftype) { + case TYPE_U8: + s->avctx->sample_fmt = AV_SAMPLE_FMT_U8P; + mean = 0x80; + break; + case TYPE_S16HL: + case TYPE_S16LH: + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "unknown audio type\n"); + return AVERROR_PATCHWELCOME; } for (chan = 0; chan < s->channels; chan++) @@ -214,53 +213,57 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, { int len, bps; 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 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 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 (len < 0 || 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 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 AVERROR_PATCHWELCOME; + 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) - bps = 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) + bps = bytestream2_get_le16(&gb); avctx->bits_per_coded_sample = bps; if (bps != 16 && bps != 8) { av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample: %d\n", bps); - return AVERROR_INVALIDDATA; + return AVERROR(ENOSYS); } len -= 16; @@ -270,7 +273,8 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, return 0; } -static const int fixed_coeffs[3][3] = { +static const int fixed_coeffs[][3] = { + { 0, 0, 0 }, { 1, 0, 0 }, { 2, -1, 0 }, { 3, -3, 1 } @@ -286,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; @@ -298,7 +303,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, } else { /* fixed LPC coeffs */ pred_order = command; - coeffs = fixed_coeffs[pred_order-1]; + if (pred_order >= FF_ARRAY_ELEMS(fixed_coeffs)) { + av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", + pred_order); + return AVERROR_INVALIDDATA; + } + coeffs = fixed_coeffs[pred_order]; qshift = 0; } @@ -309,11 +319,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 */ @@ -334,38 +345,44 @@ static int read_header(ShortenContext *s) 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 <= 0 || s->channels > MAX_CHANNELS) { + 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); + 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); @@ -379,17 +396,20 @@ 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"); + 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); + 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 ((ret = decode_wave_header(s->avctx, s->header, s->header_size)) < 0) @@ -407,17 +427,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= 8192; // should hopefully be enough for the first header + s->max_framesize = 8192; // 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); @@ -426,29 +446,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 */ @@ -470,7 +493,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, unsigned 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; } @@ -486,32 +509,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; @@ -537,7 +560,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) @@ -546,21 +569,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; @@ -569,11 +593,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 */ @@ -616,12 +640,12 @@ 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; + s->bitstream_size = 0; + s->bitstream_index = 0; return AVERROR_INVALIDDATA; } if (s->bitstream_size) { diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 1a73dcce0d..bf027e8df7 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -257,7 +257,7 @@ 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)); @@ -268,10 +268,12 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int 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){ + 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"); ctx.last[0] = ctx.last[1] = ctx.last[2] = 1; - av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n"); - return AVERROR_INVALIDDATA; + err = AVERROR_INVALIDDATA; } *recodes = huff.values; @@ -661,9 +663,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); - res = smacker_decode_tree(&gb, &h[i], 0, 0); - if (res < 0) - return res; + 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, @@ -703,7 +712,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } 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); @@ -724,7 +733,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } 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 diff --git a/libavcodec/smc.c b/libavcodec/smc.c index 6294f09691..21e1fb4e7e 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -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; \ diff --git a/libavcodec/snow.h b/libavcodec/snow.h index 2565988a57..813fcba8fc 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -313,7 +313,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){ @@ -322,7 +323,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; } @@ -648,7 +650,10 @@ static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, i if(v){ v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1); v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]); - + if ((uint16_t)v != v) { + av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n"); + v = 1; + } xc->x=x; (xc++)->coeff= v; } @@ -658,6 +663,10 @@ static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, i else run= INT_MAX; v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1); v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]); + if ((uint16_t)v != v) { + av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n"); + v = 1; + } xc->x=x; (xc++)->coeff= v; diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index c4baf0a7d1..87406eac71 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -156,7 +156,7 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){ int l = left->color[0]; int cb= left->color[1]; int cr= left->color[2]; - int ref = 0; + unsigned ref = 0; int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx)); int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my)); diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 187522c3bf..473bb806d4 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -61,6 +61,10 @@ typedef struct SVQ1Context { DSPContext dsp; GetBitContext gb; AVFrame *cur, *prev; + + uint8_t *pkt_swapped; + int pkt_swapped_allocated; + int width; int height; int frame_code; @@ -321,7 +325,8 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous, static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -350,10 +355,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, motion[x / 8 + 2].y = motion[x / 8 + 3].y = mv.y; - if (y + (mv.y >> 1) < 0) - mv.y = 0; - if (x + (mv.x >> 1) < 0) - mv.x = 0; + mv.x = av_clip(mv.x, -2 * x, 2 * (width - x - 16)); + mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16)); src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch]; dst = current; @@ -365,7 +368,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -421,10 +425,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, int mvy = pmv[i]->y + (i >> 1) * 16; // FIXME: clipping or padding? - if (y + (mvy >> 1) < 0) - mvy = 0; - if (x + (mvx >> 1) < 0) - mvx = 0; + mvx = av_clip(mvx, -2 * x, 2 * (width - x - 8)); + mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8)); src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch]; dst = current; @@ -444,7 +446,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint32_t block_type; int result = 0; @@ -469,7 +472,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, case SVQ1_BLOCK_INTER: result = svq1_motion_inter_block(dsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); @@ -480,7 +483,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, case SVQ1_BLOCK_INTER_4V: result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); @@ -497,7 +500,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, return result; } -static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) +static void svq1_parse_string(GetBitContext *bitbuf, uint8_t out[257]) { uint8_t seed; int i; @@ -509,6 +512,7 @@ static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) out[i] = get_bits(bitbuf, 8) ^ seed; seed = string_table[out[i] ^ seed]; } + out[i] = 0; } static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) @@ -551,12 +555,12 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) } if ((s->frame_code ^ 0x10) >= 0x50) { - uint8_t msg[256]; + uint8_t msg[257]; svq1_parse_string(bitbuf, msg); av_log(avctx, AV_LOG_INFO, - "embedded message: \"%s\"\n", (char *)msg); + "embedded message: \"%s\"\n", ((char *)msg) + 1); } skip_bits(bitbuf, 2); @@ -629,7 +633,24 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, /* swap some header bytes (why?) */ if (s->frame_code != 0x20) { - uint32_t *src = (uint32_t *)(buf + 4); + uint32_t *src; + + 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); if (buf_size < 36) return AVERROR_INVALIDDATA; @@ -692,7 +713,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, } else { /* delta frame */ uint8_t *previous = s->prev->data[i]; - if (!previous) { + if (!previous || + s->prev->width != s->width || s->prev->height != s->height) { av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); result = AVERROR_INVALIDDATA; goto err; @@ -705,8 +727,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, result = svq1_decode_delta_block(avctx, &s->dsp, &s->gb, ¤t[x], previous, linesize, - pmv, x, y); - if (result) { + pmv, x, y, width, height); + if (result != 0) { av_dlog(avctx, "Error in svq1_decode_delta_block %i\n", result); @@ -804,6 +826,8 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) avctx->release_buffer(avctx, s->prev); avcodec_free_frame(&s->cur); avcodec_free_frame(&s->prev); + av_freep(&s->pkt_swapped); + s->pkt_swapped_allocated = 0; return 0; } diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 2850ab0284..1b32bbc533 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -538,7 +538,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int i, ret; if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height * - MAX_MB_BYTES*3 + FF_MIN_BUFFER_SIZE) < 0)) + MAX_MB_BYTES*3 + FF_MIN_BUFFER_SIZE)) < 0) return ret; if (avctx->pix_fmt != AV_PIX_FMT_YUV410P) { @@ -547,7 +547,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } if (!s->current_picture.data[0]) { - if ((ret = ff_get_buffer(avctx, &s->current_picture) < 0) || + if ((ret = ff_get_buffer(avctx, &s->current_picture))< 0 || (ret = ff_get_buffer(avctx, &s->last_picture)) < 0) { return ret; } diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index c12c75f51b..0017608351 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -638,9 +638,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_intra_pred_mode(h, dir, 0)) == -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; @@ -962,7 +962,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int offset = get_bits_count(&gb) + 7 >> 3; uint8_t *buf; - if (watermark_height <= 0 || (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/takdec.c b/libavcodec/takdec.c index 86c1a7dda5..a904401c00 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -732,11 +732,9 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (s->ti.bps != avctx->bits_per_raw_sample) { - avctx->bits_per_raw_sample = s->ti.bps; - if ((ret = set_bps_params(avctx)) < 0) - return ret; - } + avctx->bits_per_raw_sample = s->ti.bps; + if ((ret = set_bps_params(avctx)) < 0) + return ret; if (s->ti.sample_rate != avctx->sample_rate) { avctx->sample_rate = s->ti.sample_rate; set_sample_rate_params(avctx); diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 6bb05a93ad..321441cb08 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -40,7 +40,7 @@ static uint8_t *advance_line(uint8_t *start, uint8_t *line, return line + interleave * stride; } else { *y = (*y + 1) & (interleave - 1); - if (*y) { + if (*y && *y < h) { return start + *y * stride; } else { return NULL; diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 558e748d5c..7278afbf86 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -212,10 +212,12 @@ static char *doubles2str(double *dp, int count, const char *sep) { int i; char *ap, *ap0; - int component_len; + uint64_t component_len; if (!sep) sep = ", "; - component_len = 15 + strlen(sep); - ap = av_malloc(component_len * count); + component_len = 15LL + strlen(sep); + if (count >= (INT_MAX - 1)/component_len) + return NULL; + ap = av_malloc(component_len * count + 1); if (!ap) return NULL; ap0 = ap; @@ -236,14 +238,22 @@ static char *shorts2str(int16_t *sp, int count, const char *sep) { int i; char *ap, *ap0; + uint64_t component_len; if (!sep) sep = ", "; - ap = av_malloc((5 + strlen(sep)) * count); + component_len = 7LL + strlen(sep); + if (count >= (INT_MAX - 1)/component_len) + return NULL; + ap = av_malloc(component_len * count + 1); if (!ap) return NULL; ap0 = ap; ap[0] = '\0'; for (i = 0; i < count; i++) { - int l = snprintf(ap, 5 + strlen(sep), "%d%s", sp[i], sep); + unsigned l = snprintf(ap, component_len, "%d%s", sp[i], sep); + if (l >= component_len) { + av_free(ap0); + return NULL; + } ap += l; } ap0[strlen(ap0) - strlen(sep)] = '\0'; @@ -399,6 +409,7 @@ 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; @@ -469,6 +480,18 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, 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; + } + if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) + horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); + dst += stride; + } + return 0; } if (s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4) { @@ -510,15 +533,24 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, 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 == AV_PIX_FMT_PAL8), dst, 1, src, 0, width, 0); @@ -538,15 +570,12 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, code = (int8_t) * src++; if (code >= 0) { code++; - if (pixels + code > width) { + if (pixels + code > width || + ssrc + size - src < code) { av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); return -1; } - if (ssrc + size - src < code) { - av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n"); - return AVERROR_INVALIDDATA; - } horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), dst, 1, src, 0, code, pixels); src += code; @@ -565,16 +594,6 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, } } 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 == AV_PIX_FMT_PAL8) - horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); - break; } dst += stride; } @@ -586,6 +605,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) { @@ -648,7 +675,8 @@ static int init_image(TiffContext *s) static int tiff_decode_tag(TiffContext *s) { unsigned tag, type, count, off, value = 0; - int i, j, k, pos, start; + int i, start; + int j, k, pos; int ret; uint32_t *pal; double *dp; @@ -700,13 +728,13 @@ static int tiff_decode_tag(TiffContext *s) s->height = value; break; case TIFF_BPP: - s->bppcount = count; - if (count > 4) { + if (count > 4U) { av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", - s->bpp, count); + value, count); return -1; } + s->bppcount = count; if (count == 1) s->bpp = value; else { @@ -790,27 +818,17 @@ static int tiff_decode_tag(TiffContext *s) if (s->strips == 1) s->rps = s->height; s->sot = type; - if (s->strippos > bytestream2_size(&s->gb)) { - 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->stripsizesoff = 0; - s->stripsize = value; - s->strips = 1; + s->stripsize = value; + s->strips = 1; } else { s->stripsizesoff = off; } s->strips = count; s->sstype = type; - if (s->stripsizesoff > bytestream2_size(&s->gb)) { - 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: @@ -847,11 +865,13 @@ static int tiff_decode_tag(TiffContext *s) } s->fill_order = value - 1; break; - case TIFF_PAL: + case TIFF_PAL: { pal = (uint32_t *) s->palette; off = type_sizes[type]; - if (count / 3 > 256 || bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3) + if (count / 3 > 256 || + bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3) return -1; + off = (type_sizes[type] - 1) << 3; for (k = 2; k >= 0; k--) { for (i = 0; i < count / 3; i++) { @@ -863,6 +883,7 @@ static int tiff_decode_tag(TiffContext *s) } 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"); @@ -878,7 +899,7 @@ static int tiff_decode_tag(TiffContext *s) s->fax_opts = value; break; #define ADD_METADATA(count, name, sep)\ - if (ret = add_metadata(count, type, name, sep, s) < 0) {\ + if ((ret = add_metadata(count, type, name, sep, s)) < 0) {\ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\ return ret;\ } @@ -1009,6 +1030,13 @@ static int tiff_decode_tag(TiffContext *s) 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; } @@ -1112,12 +1140,14 @@ static int decode_frame(AVCodecContext *avctx, if (s->stripsizesoff) { if (s->stripsizesoff >= (unsigned)avpkt->size) return AVERROR_INVALIDDATA; - bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, avpkt->size - s->stripsizesoff); + bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, + avpkt->size - s->stripsizesoff); } if (s->strippos) { if (s->strippos >= (unsigned)avpkt->size) return AVERROR_INVALIDDATA; - bytestream2_init(&stripdata, avpkt->data + s->strippos, avpkt->size - s->strippos); + bytestream2_init(&stripdata, avpkt->data + s->strippos, + avpkt->size - s->strippos); } if (s->rps <= 0) { @@ -1127,12 +1157,12 @@ static int decode_frame(AVCodecContext *avctx, for (i = 0; i < s->height; i += s->rps) { if (s->stripsizesoff) - ssize = tget(&stripsizes, s->sstype, s->le); + ssize = tget(&stripsizes, s->sstype, le); else ssize = s->stripsize; if (s->strippos) - soff = tget(&stripdata, s->sot, s->le); + soff = tget(&stripdata, s->sot, le); else soff = s->stripoff; diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index e2c1d2804a..dc30b6e8b3 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -322,6 +322,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 */ for (i = 1; i < header.header_size; i++) header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1]; @@ -513,6 +518,15 @@ hres,vres,i,i%vres (0 < i < 4) index = s->index_stream[index_stream_index++] * 4; \ } +#define INC_INDEX \ +do { \ + if (index >= 1023) { \ + av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \ + return; \ + } \ + index++; \ +} while (0) + #define APPLY_C_PREDICTOR() \ if(index > 1023){\ av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ @@ -529,10 +543,10 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define APPLY_C_PREDICTOR_24() \ if(index > 1023){\ @@ -550,10 +564,10 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define APPLY_Y_PREDICTOR() \ @@ -572,10 +586,10 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define APPLY_Y_PREDICTOR_24() \ if(index > 1023){\ @@ -593,10 +607,10 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define OUTPUT_PIXEL_PAIR() \ *current_pixel_pair = *vert_pred + horiz_pred; \ diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 5ba2cf10e7..3b5b09e98e 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -922,14 +922,14 @@ static av_cold int decode_init(AVCodecContext *avctx){ 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); + 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; diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index b34f159485..6dba7b91be 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -1142,12 +1142,12 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) AV_CH_LAYOUT_STEREO; ibps = avctx->bit_rate / (1000 * avctx->channels); - - if (ibps > 255U) { - av_log(avctx, AV_LOG_ERROR, "unsupported per channel bitrate %dkbps\n", ibps); + 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; case (11<<8) + 8: tctx->mtab = &mode_11_08; break; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index f5ceae4e17..0d823955ff 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -183,6 +183,12 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int i; int w_align = 1; int h_align = 1; + AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt); + + if (desc) { + w_align = 1 << desc->log2_chroma_w; + h_align = 1 << desc->log2_chroma_h; + } switch (s->pix_fmt) { case AV_PIX_FMT_YUV420P: @@ -234,13 +240,15 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_GBRP12BE: case AV_PIX_FMT_GBRP14LE: case AV_PIX_FMT_GBRP14BE: + case AV_PIX_FMT_GBRP16LE: + case AV_PIX_FMT_GBRP16BE: w_align = 16; //FIXME assume 16 pixel per macroblock h_align = 16 * 2; // interlaced needs 2 macroblocks height break; case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_UYYVYY411: w_align = 32; - h_align = 8; + h_align = 16 * 2; break; case AV_PIX_FMT_YUV410P: if (s->codec_id == AV_CODEC_ID_SVQ1) { @@ -261,6 +269,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align = 4; h_align = 4; } + if (s->codec_id == AV_CODEC_ID_JV) { + w_align = 8; + h_align = 8; + } break; case AV_PIX_FMT_BGR24: if ((s->codec_id == AV_CODEC_ID_MSZH) || @@ -270,8 +282,6 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, } break; default: - w_align = 1; - h_align = 1; break; } @@ -540,6 +550,11 @@ void ff_init_buffer_info(AVCodecContext *s, AVFrame *frame) int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame) { + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) + return AVERROR_INVALIDDATA; + } + ff_init_buffer_info(avctx, frame); return avctx->get_buffer(avctx, frame); @@ -1018,6 +1033,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code && avctx->bit_rate>0 && avctx->bit_rate<1000) { av_log(avctx, AV_LOG_WARNING, "Bitrate %d is extreemly low, did you mean %dk\n", avctx->bit_rate, avctx->bit_rate); } + + if (!avctx->rc_initial_buffer_occupancy) + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3 / 4; } avctx->pts_correction_num_faulty_pts = @@ -1764,7 +1782,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n", avctx->internal->skip_samples); } - if (avctx->internal->skip_samples) { + if (avctx->internal->skip_samples && *got_frame_ptr) { if(frame->nb_samples <= avctx->internal->skip_samples){ *got_frame_ptr = 0; avctx->internal->skip_samples -= frame->nb_samples; @@ -1806,7 +1824,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, * extended_data are doing it correctly */ if (*got_frame_ptr) { planar = av_sample_fmt_is_planar(frame->format); - channels = av_get_channel_layout_nb_channels(frame->channel_layout); + channels = frame->channels; if (!(planar && channels > AV_NUM_DATA_POINTERS)) frame->extended_data = frame->data; } else { @@ -2695,6 +2713,11 @@ int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) ret = av_bprint_finalize(buf, &str); if (ret < 0) return ret; + if (!av_bprint_is_complete(buf)) { + av_free(str); + return AVERROR(ENOMEM); + } + avctx->extradata = str; /* Note: the string is NUL terminated (so extradata can be read as a * string), but the ending character is not accounted in the size (in diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 259030aac5..188322dff8 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -212,6 +212,8 @@ static void restore_median(uint8_t *src, int step, int stride, slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; + if (!slice_height) + continue; bsrc = src + slice_start * stride; // first line - left neighbour prediction @@ -222,7 +224,7 @@ static void restore_median(uint8_t *src, int step, int stride, A = bsrc[i]; } bsrc += stride; - if (slice_height == 1) + if (slice_height <= 1) continue; // second line - first element has top prediction, the rest uses median C = bsrc[-stride]; @@ -267,6 +269,8 @@ static void restore_median_il(uint8_t *src, int step, int stride, slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; slice_height >>= 1; + if (!slice_height) + continue; bsrc = src + slice_start * stride; @@ -282,7 +286,7 @@ static void restore_median_il(uint8_t *src, int step, int stride, A = bsrc[stride + i]; } bsrc += stride2; - if (slice_height == 1) + if (slice_height <= 1) continue; // second line - first element has top prediction, the rest uses median C = bsrc[-stride2]; diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index 7167278351..17c42456c4 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -468,7 +468,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, * get the offset in bits and convert to bytes. */ offset += write_huff_codes(dst + sstart * width, c->slice_bits, - width * (send - sstart), width, + width * height + 4, width, send - sstart, he) >> 3; slice_len = offset - slice_len; @@ -525,8 +525,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_init_writer(&pb, dst, pkt->size); - av_fast_malloc(&c->slice_bits, &c->slice_bits_size, - width * height + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&c->slice_bits, &c->slice_bits_size, width * height + 4); if (!c->slice_bits) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n"); diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index fa0b916898..2ecef4277c 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -581,6 +581,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; + v->field_mode = 0; + v->fcm = 0; if (v->finterpflag) v->interpfrm = get_bits1(gb); if (!v->s.avctx->codec) @@ -836,7 +838,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) int scale, shift, i; /* for initializing LUT for intensity compensation */ int field_mode, fcm; - v->numref=0; + v->numref = 0; v->p_frame_skipped = 0; if (v->second_field) { if(v->fcm!=2 || v->field_mode!=1) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index bdab48ca7f..270f91a5de 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -395,8 +395,10 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } } - if(!srcY) + 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); @@ -573,8 +575,10 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) } else srcY = s->next_picture.f.data[0]; - if(!srcY) + 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]) @@ -865,8 +869,10 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcV = s->next_picture.f.data[2]; } - if(!srcU) + if (!srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); return; + } srcU += uvsrc_y * s->uvlinesize + uvsrc_x; srcV += uvsrc_y * s->uvlinesize + uvsrc_x; @@ -1149,8 +1155,12 @@ static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, *dmv_x = get_bits(gb, v->k_x); *dmv_y = get_bits(gb, v->k_y); if (v->numref) { - *pred_flag = *dmv_y & 1; - *dmv_y = (*dmv_y + *pred_flag) >> 1; + if (pred_flag) { + *pred_flag = *dmv_y & 1; + *dmv_y = (*dmv_y + *pred_flag) >> 1; + } else { + *dmv_y = (*dmv_y + (*dmv_y & 1)) >> 1; + } } } else { @@ -1177,7 +1187,7 @@ static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign; } else *dmv_y = 0; - if (v->numref) + if (v->numref && pred_flag) *pred_flag = index1 & 1; } } @@ -4740,6 +4750,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++) { @@ -5131,8 +5144,19 @@ av_cold int ff_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; } @@ -5504,8 +5528,12 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } if (!s->context_initialized) { - if (ff_msmpeg4_decode_init(avctx) < 0 || ff_vc1_decode_init_alloc_tables(v) < 0) + if (ff_msmpeg4_decode_init(avctx) < 0) goto err; + if (ff_vc1_decode_init_alloc_tables(v) < 0) { + ff_MPV_common_end(s); + goto err; + } s->low_delay = !avctx->has_b_frames || v->res_sprite; @@ -5638,6 +5666,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, goto err; } } else { + int header_ret = 0; if (v->fcm == ILACE_FRAME && s->pict_type == AV_PICTURE_TYPE_B) goto err; // This codepath is still incomplete thus it is disabled @@ -5662,6 +5691,12 @@ 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) { @@ -5681,18 +5716,20 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (i) { v->pic_header_flag = 0; if (v->field_mode && i == n_slices1 + 2) { - if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { + if ((header_ret = ff_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; - if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { + if ((header_ret = ff_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); diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c index 778ad0d8c2..04a6b3183d 100644 --- a/libavcodec/vcr1.c +++ b/libavcodec/vcr1.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "dsputil.h" #include "internal.h" +#include "libavutil/avassert.h" #include "libavutil/internal.h" typedef struct VCR1Context { @@ -52,9 +53,10 @@ static av_cold int vcr1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV410P; if (avctx->width % 8 || avctx->height%4) { - av_log_ask_for_sample(avctx, "odd dimensions are not supported\n"); - return AVERROR_PATCHWELCOME; + av_log_ask_for_sample(avctx, "odd dimensions (%d x %d) support", avctx->width, avctx->height); + return AVERROR_INVALIDDATA; } + return 0; } @@ -98,6 +100,7 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < 16; i++) { a->delta[i] = *bytestream++; bytestream++; + buf_size--; } for (y = 0; y < avctx->height; y++) { @@ -108,8 +111,11 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, 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]]; + av_assert0 (buf_size >= 4 + avctx->width); + 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; x < avctx->width; x += 4) { @@ -123,8 +129,11 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, *cr++ = bytestream[1]; bytestream += 4; + buf_size -= 4; } } else { + av_assert0 (buf_size >= avctx->width / 2); + offset = a->offset[y & 3] - a->delta[bytestream[2] & 0xF]; for (x = 0; x < avctx->width; x += 8) { @@ -138,6 +147,7 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, luma[7] = offset += a->delta[bytestream[1] >> 4]; luma += 8; bytestream += 4; + buf_size -= 4; } } } @@ -145,7 +155,7 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, *picture = a->picture; *got_frame = 1; - return buf_size; + return bytestream - avpkt->data; } AVCodec ff_vcr1_decoder = { diff --git a/libavcodec/videodsp.h b/libavcodec/videodsp.h index dc893847b3..5a79e661f0 100644 --- a/libavcodec/videodsp.h +++ b/libavcodec/videodsp.h @@ -29,6 +29,8 @@ #include #include +typedef int emuedge_linesize_type; + typedef struct VideoDSPContext { /** * Copy a rectangular area of samples to a temporary buffer and replicate diff --git a/libavcodec/videodsp_template.c b/libavcodec/videodsp_template.c index 44f6a4d63e..1f709c499d 100644 --- a/libavcodec/videodsp_template.c +++ b/libavcodec/videodsp_template.c @@ -27,7 +27,7 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, { int x, y; int start_y, start_x, end_y, end_x; - int linesize = linesize_arg; + emuedge_linesize_type linesize = linesize_arg; if (!w || !h) return; diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 6da60c14a1..f17bd493f0 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -43,11 +43,13 @@ #include #include +#include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" +#include "bytestream.h" #define VMD_HEADER_SIZE 0x330 #define PALETTE_COUNT 256 @@ -78,8 +80,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]; @@ -90,19 +90,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 { @@ -110,13 +108,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; @@ -125,21 +123,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; @@ -156,64 +150,59 @@ 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; + int i, j, 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; - for (i = 0; i < l; i++) { + int ps[2]; + if (dest_end - pd < 2*l || bytestream2_get_bytes_left(&gb) < 2) + return bytestream2_tell(&gb); + ps[0] = bytestream2_get_byteu(&gb); + ps[1] = bytestream2_get_byteu(&gb); + for (j = 0; j < l; j++) { *pd++ = ps[0]; *pd++ = ps[1]; } - ps += 2; } i += l; } while (i < src_count); - return ps - src; + return bytestream2_tell(&gb); } -static void vmd_decode(VmdVideoContext *s) +static int vmd_decode(VmdVideoContext *s) { int i; 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 */ @@ -230,13 +219,21 @@ static void vmd_decode(VmdVideoContext *s) if (frame_x < 0 || frame_width < 0 || frame_x >= s->avctx->width || frame_width > s->avctx->width || - frame_x + frame_width > s->avctx->width) - return; + frame_x + frame_width > s->avctx->width) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid horizontal range %d-%d\n", + frame_x, frame_width); + return AVERROR_INVALIDDATA; + } if (frame_y < 0 || frame_height < 0 || frame_y >= s->avctx->height || frame_height > s->avctx->height || - frame_y + frame_height > s->avctx->height) - return; + frame_y + frame_height > s->avctx->height) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid vertical range %d-%d\n", + frame_x, frame_width); + return AVERROR_INVALIDDATA; + } if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && (frame_x || frame_y)) { @@ -258,115 +255,118 @@ 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] = 0xFFU << 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; + } + } else { + av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n"); + return AVERROR_INVALIDDATA; } } - if (p < p_end) { - /* originally UnpackFrame in VAG's code */ - pb = p; - pb_end = p_end; - meth = *pb++; - if (meth & 0x80) { - lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); - meth &= 0x7F; - pb = s->unpack_buffer; - pb_end = s->unpack_buffer + s->unpack_buffer_size; - } - dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; - pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; - switch (meth) { - case 1: - for (i = 0; i < frame_height; i++) { - ofs = 0; - do { - if (pb_end - pb < 1) - return; - len = *pb++; - if (len & 0x80) { - len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_end - pb < len) - return; - memcpy(&dp[ofs], pb, len); - pb += len; - ofs += len; - } else { - /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) - return; - memcpy(&dp[ofs], &pp[ofs], len + 1); - ofs += len + 1; - } - } while (ofs < frame_width); - if (ofs > frame_width) { - av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n", - ofs, frame_width); - break; - } - dp += s->frame.linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; + if (!s->size) + return 0; - case 2: - for (i = 0; i < frame_height; i++) { - if (pb_end -pb < frame_width) - return; - memcpy(dp, pb, frame_width); - pb += frame_width; - dp += s->frame.linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; - - case 3: - for (i = 0; i < frame_height; i++) { - ofs = 0; - do { - if (pb_end - pb < 1) - return; - len = *pb++; - 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); - else { - if (pb_end - pb < len) - return; - memcpy(&dp[ofs], pb, len); - } - pb += len; - ofs += len; - } else { - /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) - return; - memcpy(&dp[ofs], &pp[ofs], len + 1); - ofs += len + 1; - } - } while (ofs < frame_width); - if (ofs > frame_width) { - av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n", - ofs, frame_width); - } - dp += s->frame.linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; - } + /* originally UnpackFrame in VAG's code */ + if (bytestream2_get_bytes_left(&gb) < 1) + return AVERROR_INVALIDDATA; + meth = bytestream2_get_byteu(&gb); + if (meth & 0x80) { + lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), + s->unpack_buffer, s->unpack_buffer_size); + meth &= 0x7F; + bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); } + + dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; + pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; + switch (meth) { + case 1: + for (i = 0; i < frame_height; i++) { + ofs = 0; + do { + len = bytestream2_get_byte(&gb); + if (len & 0x80) { + len = (len & 0x7F) + 1; + if (ofs + len > frame_width || + bytestream2_get_bytes_left(&gb) < len) + return AVERROR_INVALIDDATA; + bytestream2_get_buffer(&gb, &dp[ofs], len); + ofs += len; + } else { + /* interframe pixel copy */ + if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) + return AVERROR_INVALIDDATA; + memcpy(&dp[ofs], &pp[ofs], len + 1); + ofs += len + 1; + } + } while (ofs < frame_width); + if (ofs > frame_width) { + av_log(s->avctx, AV_LOG_ERROR, + "VMD video: offset > width (%d > %d)\n", + ofs, frame_width); + return AVERROR_INVALIDDATA; + } + dp += s->frame.linesize[0]; + pp += s->prev_frame.linesize[0]; + } + break; + + case 2: + for (i = 0; i < frame_height; i++) { + bytestream2_get_buffer(&gb, dp, frame_width); + dp += s->frame.linesize[0]; + pp += s->prev_frame.linesize[0]; + } + break; + + case 3: + for (i = 0; i < frame_height; i++) { + ofs = 0; + do { + len = bytestream2_get_byte(&gb); + if (len & 0x80) { + len = (len & 0x7F) + 1; + if (bytestream2_get_byte(&gb) == 0xFF) + len = rle_unpack(gb.buffer, &dp[ofs], + len, bytestream2_get_bytes_left(&gb), + frame_width - ofs); + else { + if (ofs + len > frame_width || + bytestream2_get_bytes_left(&gb) < len) + return AVERROR_INVALIDDATA; + bytestream2_get_buffer(&gb, &dp[ofs], len); + } + bytestream2_skip(&gb, len); + } else { + /* interframe pixel copy */ + if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) + return AVERROR_INVALIDDATA; + memcpy(&dp[ofs], &pp[ofs], len + 1); + ofs += len + 1; + } + } while (ofs < frame_width); + if (ofs > frame_width) { + av_log(s->avctx, AV_LOG_ERROR, + "VMD video: offset > width (%d > %d)\n", + ofs, frame_width); + return AVERROR_INVALIDDATA; + } + dp += s->frame.linesize[0]; + pp += s->prev_frame.linesize[0]; + } + break; + } + return 0; } static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) @@ -423,7 +423,7 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, s->size = buf_size; if (buf_size < 16) - return buf_size; + return AVERROR_INVALIDDATA; s->frame.reference = 3; if (ff_get_buffer(avctx, &s->frame)) { @@ -600,6 +600,9 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* ensure output buffer is large enough */ audio_chunks = buf_size / s->chunk_size; + /* drop incomplete chunks */ + buf_size = audio_chunks * s->chunk_size; + /* get output buffer */ s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels; if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { @@ -611,7 +614,8 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* decode silent chunks */ if (silent_chunks > 0) { - int silent_size = avctx->block_align * silent_chunks; + int silent_size = FFMIN(avctx->block_align * silent_chunks, + s->frame.nb_samples * avctx->channels); if (s->out_bps == 2) { memset(output_samples_s16, 0x00, silent_size * 2); output_samples_s16 += silent_size; @@ -624,7 +628,8 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* decode audio chunks */ if (audio_chunks > 0) { buf_end = buf + buf_size; - while ( buf_end - buf >= s->chunk_size) { + av_assert0((buf_size & (avctx->channels > 1)) == 0); + while (buf_end - buf >= s->chunk_size) { if (s->out_bps == 2) { decode_audio_s16(output_samples_s16, buf, s->chunk_size, avctx->channels); diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index eb39fc923d..bb2ef6bdd2 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -31,6 +31,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bytestream.h" enum EncTypes { MAGIC_WMVd = 0x574D5664, @@ -62,55 +63,66 @@ typedef struct VmncContext { int bigendian; uint8_t pal[768]; int width, height; + GetByteContext gb; /* cursor data */ int cur_w, cur_h; int cur_x, cur_y; int cur_hx, cur_hy; - uint8_t* curbits, *curmask; - uint8_t* screendta; + uint8_t *curbits, *curmask; + uint8_t *screendta; } VmncContext; /* read pixel value from stream */ -static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) { - switch(bpp * 2 + be) { +static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be) +{ + switch (bpp * 2 + be) { case 2: - case 3: return *buf; - case 4: return AV_RL16(buf); - case 5: return AV_RB16(buf); - case 8: return AV_RL32(buf); - case 9: return AV_RB32(buf); + case 3: + return bytestream2_get_byte(gb); + case 4: + return bytestream2_get_le16(gb); + case 5: + return bytestream2_get_be16(gb); + case 8: + return bytestream2_get_le32(gb); + case 9: + return bytestream2_get_be32(gb); default: return 0; } } -static void load_cursor(VmncContext *c, const uint8_t *src) +static void load_cursor(VmncContext *c) { int i, j, p; - const int bpp = c->bpp2; - uint8_t *dst8 = c->curbits; - uint16_t *dst16 = (uint16_t*)c->curbits; - uint32_t *dst32 = (uint32_t*)c->curbits; + const int bpp = c->bpp2; + uint8_t *dst8 = c->curbits; + uint16_t *dst16 = (uint16_t *)c->curbits; + uint32_t *dst32 = (uint32_t *)c->curbits; - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { - p = vmnc_get_pixel(src, bpp, c->bigendian); - src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; + for (j = 0; j < c->cur_h; j++) { + for (i = 0; i < c->cur_w; i++) { + p = vmnc_get_pixel(&c->gb, bpp, c->bigendian); + if (bpp == 1) + *dst8++ = p; + if (bpp == 2) + *dst16++ = p; + if (bpp == 4) + *dst32++ = p; } } - dst8 = c->curmask; + dst8 = c->curmask; dst16 = (uint16_t*)c->curmask; dst32 = (uint32_t*)c->curmask; - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { - p = vmnc_get_pixel(src, bpp, c->bigendian); - src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; + for (j = 0; j < c->cur_h; j++) { + for (i = 0; i < c->cur_w; i++) { + p = vmnc_get_pixel(&c->gb, bpp, c->bigendian); + if (bpp == 1) + *dst8++ = p; + if (bpp == 2) + *dst16++ = p; + if (bpp == 4) + *dst32++ = p; } } } @@ -120,96 +132,100 @@ static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy) int i, j; int w, h, x, y; w = c->cur_w; - if(c->width < c->cur_x + c->cur_w) w = c->width - c->cur_x; + if (c->width < c->cur_x + c->cur_w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + c->cur_h) h = c->height - c->cur_y; + if (c->height < c->cur_y + c->cur_h) + h = c->height - c->cur_y; x = c->cur_x; y = c->cur_y; - if(x < 0) { + if (x < 0) { w += x; - x = 0; + x = 0; } - if(y < 0) { + if (y < 0) { h += y; - y = 0; + y = 0; } - if((w < 1) || (h < 1)) return; + if ((w < 1) || (h < 1)) + return; dst += x * c->bpp2 + y * stride; - if(c->bpp2 == 1) { - uint8_t* cd = c->curbits, *msk = c->curmask; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) + if (c->bpp2 == 1) { + uint8_t *cd = c->curbits, *msk = c->curmask; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) dst[i] = (dst[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } - } else if(c->bpp2 == 2) { - uint16_t* cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; - uint16_t* dst2; - for(j = 0; j < h; j++) { + } else if (c->bpp2 == 2) { + uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; + uint16_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) + for (i = 0; i < w; i++) dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } - } else if(c->bpp2 == 4) { - uint32_t* cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; - uint32_t* dst2; - for(j = 0; j < h; j++) { + } else if (c->bpp2 == 4) { + uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; + uint32_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) + for (i = 0; i < w; i++) dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } } } /* fill rectangle with given color */ -static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride) +static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, + int w, int h, int color, + int bpp, int stride) { int i, j; dst += dx * bpp + dy * stride; - if(bpp == 1){ - for(j = 0; j < h; j++) { + if (bpp == 1) { + for (j = 0; j < h; j++) { memset(dst, color, w); dst += stride; } - }else if(bpp == 2){ - uint16_t* dst2; - for(j = 0; j < h; j++) { + } else if (bpp == 2) { + uint16_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) { + for (i = 0; i < w; i++) *dst2++ = color; - } dst += stride; } - }else if(bpp == 4){ - uint32_t* dst2; - for(j = 0; j < h; j++) { + } else if (bpp == 4) { + uint32_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) { + for (i = 0; i < w; i++) dst2[i] = color; - } dst += stride; } } } -static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride) +static av_always_inline void paint_raw(uint8_t *dst, int w, int h, + GetByteContext *gb, int bpp, + int be, int stride) { int i, j, p; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) { - p = vmnc_get_pixel(src, bpp, be); - src += bpp; - switch(bpp){ + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + p = vmnc_get_pixel(gb, bpp, be); + switch (bpp) { case 1: dst[i] = p; break; @@ -225,74 +241,86 @@ static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t } } -static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride) +static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb, + int w, int h, int stride) { int i, j, k; int bg = 0, fg = 0, rects, color, flags, xy, wh; const int bpp = c->bpp2; uint8_t *dst2; int bw = 16, bh = 16; - const uint8_t *ssrc=src; - for(j = 0; j < h; j += 16) { + for (j = 0; j < h; j += 16) { dst2 = dst; - bw = 16; - if(j + 16 > h) bh = h - j; - for(i = 0; i < w; i += 16, dst2 += 16 * bpp) { - if(src - ssrc >= ssize) { + bw = 16; + if (j + 16 > h) + bh = h - j; + for (i = 0; i < w; i += 16, dst2 += 16 * bpp) { + if (bytestream2_get_bytes_left(gb) <= 0) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - if(i + 16 > w) bw = w - i; - flags = *src++; - if(flags & HT_RAW) { - if(src - ssrc > ssize - bw * bh * bpp) { + if (i + 16 > w) + bw = w - i; + flags = bytestream2_get_byte(gb); + if (flags & HT_RAW) { + if (bytestream2_get_bytes_left(gb) < bw * bh * bpp) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride); - src += bw * bh * bpp; + paint_raw(dst2, bw, bh, gb, bpp, c->bigendian, stride); } else { - if(flags & HT_BKG) { - bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } - if(flags & HT_FG) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } + if (flags & HT_BKG) + bg = vmnc_get_pixel(gb, bpp, c->bigendian); + if (flags & HT_FG) + fg = vmnc_get_pixel(gb, bpp, c->bigendian); rects = 0; - if(flags & HT_SUB) - rects = *src++; + if (flags & HT_SUB) + rects = bytestream2_get_byte(gb); color = !!(flags & HT_CLR); paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride); - if(src - ssrc > ssize - rects * (color * bpp + 2)) { + if (bytestream2_get_bytes_left(gb) < rects * (color * bpp + 2)) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - for(k = 0; k < rects; k++) { - if(color) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; + for (k = 0; k < rects; k++) { + if (color) + fg = vmnc_get_pixel(gb, bpp, c->bigendian); + xy = bytestream2_get_byte(gb); + wh = bytestream2_get_byte(gb); + if ( (xy >> 4) + (wh >> 4) + 1 > w - i + || (xy & 0xF) + (wh & 0xF)+1 > h - j) { + av_log(c->avctx, AV_LOG_ERROR, "Rectangle outside picture\n"); + return AVERROR_INVALIDDATA; } - xy = *src++; - wh = *src++; - paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); + paint_rect(dst2, xy >> 4, xy & 0xF, + (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); } } } dst += stride * 16; } - return src - ssrc; + return 0; +} + +static void reset_buffers(VmncContext *c) +{ + av_freep(&c->curbits); + av_freep(&c->curmask); + av_freep(&c->screendta); + c->cur_w = c->cur_h = 0; } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size = avpkt->size; VmncContext * const c = avctx->priv_data; + GetByteContext *gb = &c->gb; uint8_t *outptr; - const uint8_t *src = buf; int dx, dy, w, h, depth, enc, chunks, res, size_left; c->pic.reference = 3; @@ -302,187 +330,209 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return -1; } + bytestream2_init(gb, buf, buf_size); + c->pic.key_frame = 0; c->pic.pict_type = AV_PICTURE_TYPE_P; - //restore screen after cursor - if(c->screendta) { + // restore screen after cursor + if (c->screendta) { int i; w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; + if (c->width < c->cur_x + w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; + if (c->height < c->cur_y + h) + h = c->height - c->cur_y; dx = c->cur_x; - if(dx < 0) { + if (dx < 0) { w += dx; dx = 0; } dy = c->cur_y; - if(dy < 0) { + if (dy < 0) { h += dy; dy = 0; } - if((w > 0) && (h > 0)) { + if ((w > 0) && (h > 0)) { outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2); + for (i = 0; i < h; i++) { + memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, + w * c->bpp2); outptr += c->pic.linesize[0]; } } } - src += 2; - chunks = AV_RB16(src); src += 2; - while(chunks--) { - if(buf_size - (src - buf) < 12) { + bytestream2_skip(gb, 2); + chunks = bytestream2_get_be16(gb); + while (chunks--) { + if (bytestream2_get_bytes_left(gb) < 12) { av_log(avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - dx = AV_RB16(src); src += 2; - dy = AV_RB16(src); src += 2; - w = AV_RB16(src); src += 2; - h = AV_RB16(src); src += 2; - enc = AV_RB32(src); src += 4; + dx = bytestream2_get_be16(gb); + dy = bytestream2_get_be16(gb); + w = bytestream2_get_be16(gb); + h = bytestream2_get_be16(gb); + enc = bytestream2_get_be32(gb); outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - size_left = buf_size - (src - buf); - switch(enc) { + size_left = bytestream2_get_bytes_left(gb); + switch (enc) { case MAGIC_WMVd: // cursor if (w*(int64_t)h*c->bpp2 > INT_MAX/2 - 2) { av_log(avctx, AV_LOG_ERROR, "dimensions too large\n"); return AVERROR_INVALIDDATA; } if(size_left < 2 + w * h * c->bpp2 * 2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left); + av_log(avctx, AV_LOG_ERROR, + "Premature end of data! (need %i got %i)\n", + 2 + w * h * c->bpp2 * 2, size_left); return -1; } - src += 2; - c->cur_w = w; - c->cur_h = h; + bytestream2_skip(gb, 2); + c->cur_w = w; + c->cur_h = h; c->cur_hx = dx; c->cur_hy = dy; - if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { - av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); + if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { + av_log(avctx, AV_LOG_ERROR, + "Cursor hot spot is not in image: " + "%ix%i of %ix%i cursor size\n", + c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); c->cur_hx = c->cur_hy = 0; } - c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2); - c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2); - c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2); - load_cursor(c, src); - src += w * h * c->bpp2 * 2; + if (c->cur_w * c->cur_h >= INT_MAX / c->bpp2) { + reset_buffers(c); + return AVERROR(EINVAL); + } else { + int screen_size = c->cur_w * c->cur_h * c->bpp2; + if ((c->curbits = av_realloc(c->curbits, screen_size)) == NULL || + (c->curmask = av_realloc(c->curmask, screen_size)) == NULL || + (c->screendta = av_realloc(c->screendta, screen_size)) == NULL) { + reset_buffers(c); + return screen_size ? AVERROR(ENOMEM) : 0; + } + } + load_cursor(c); break; case MAGIC_WMVe: // unknown - src += 2; + bytestream2_skip(gb, 2); break; case MAGIC_WMVf: // update cursor position c->cur_x = dx - c->cur_hx; c->cur_y = dy - c->cur_hy; break; case MAGIC_WMVg: // unknown - src += 10; + bytestream2_skip(gb, 10); break; case MAGIC_WMVh: // unknown - src += 4; + bytestream2_skip(gb, 4); break; case MAGIC_WMVi: // ServerInitialization struct c->pic.key_frame = 1; c->pic.pict_type = AV_PICTURE_TYPE_I; - depth = *src++; - if(depth != c->bpp) { - av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth); + depth = bytestream2_get_byte(gb); + if (depth != c->bpp) { + av_log(avctx, AV_LOG_INFO, + "Depth mismatch. Container %i bpp, " + "Frame data: %i bpp\n", + c->bpp, depth); } - src++; - c->bigendian = *src++; - if(c->bigendian & (~1)) { - av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian); + bytestream2_skip(gb, 1); + c->bigendian = bytestream2_get_byte(gb); + if (c->bigendian & (~1)) { + av_log(avctx, AV_LOG_INFO, + "Invalid header: bigendian flag = %i\n", c->bigendian); return -1; } //skip the rest of pixel format data - src += 13; + bytestream2_skip(gb, 13); break; case MAGIC_WMVj: // unknown - src += 2; + bytestream2_skip(gb, 2); break; case 0x00000000: // raw rectangle data - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); + if ((dx + w > c->width) || (dy + h > c->height)) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", + w, h, dx, dy, c->width, c->height); return -1; } - if(size_left < w * h * c->bpp2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left); + if (size_left < w * h * c->bpp2) { + av_log(avctx, AV_LOG_ERROR, + "Premature end of data! (need %i got %i)\n", + w * h * c->bpp2, size_left); return -1; } - paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]); - src += w * h * c->bpp2; + paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian, + c->pic.linesize[0]); break; case 0x00000005: // HexTile encoded rectangle - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); + if ((dx + w > c->width) || (dy + h > c->height)) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", + w, h, dx, dy, c->width, c->height); return -1; } - res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]); - if(res < 0) + res = decode_hextile(c, outptr, gb, w, h, c->pic.linesize[0]); + if (res < 0) return -1; - src += res; break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc); chunks = 0; // leave chunks decoding loop } } - if(c->screendta){ + if (c->screendta) { int i; - //save screen data before painting cursor + // save screen data before painting cursor w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; + if (c->width < c->cur_x + w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; + if (c->height < c->cur_y + h) + h = c->height - c->cur_y; dx = c->cur_x; - if(dx < 0) { + if (dx < 0) { w += dx; dx = 0; } dy = c->cur_y; - if(dy < 0) { + if (dy < 0) { h += dy; dy = 0; } - if((w > 0) && (h > 0)) { + if ((w > 0) && (h > 0)) { outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2); + for (i = 0; i < h; i++) { + memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, + w * c->bpp2); outptr += c->pic.linesize[0]; } outptr = c->pic.data[0]; put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y); } } - *got_frame = 1; + *got_frame = 1; *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; } - - -/* - * - * Init VMnc decoder - * - */ static av_cold int decode_init(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; - c->avctx = avctx; - - c->width = avctx->width; + c->avctx = avctx; + c->width = avctx->width; c->height = avctx->height; + c->bpp = avctx->bits_per_coded_sample; + c->bpp2 = c->bpp / 8; - c->bpp = avctx->bits_per_coded_sample; - c->bpp2 = c->bpp/8; avcodec_get_frame_defaults(&c->pic); - switch(c->bpp){ + switch (c->bpp) { case 8: avctx->pix_fmt = AV_PIX_FMT_PAL8; break; @@ -500,13 +550,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } - - -/* - * - * Uninit VMnc decoder - * - */ static av_cold int decode_end(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 45096322f7..dd4a8bc810 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -195,37 +195,41 @@ static void vorbis_free(vorbis_context *vc) av_freep(&vc->channel_residues); av_freep(&vc->saved); - for (i = 0; i < vc->residue_count; i++) - av_free(vc->residues[i].classifs); + if (vc->residues) + for (i = 0; i < vc->residue_count; i++) + av_free(vc->residues[i].classifs); av_freep(&vc->residues); av_freep(&vc->modes); ff_mdct_end(&vc->mdct[0]); ff_mdct_end(&vc->mdct[1]); - for (i = 0; i < vc->codebook_count; ++i) { - av_free(vc->codebooks[i].codevectors); - ff_free_vlc(&vc->codebooks[i].vlc); - } + if (vc->codebooks) + for (i = 0; i < vc->codebook_count; ++i) { + av_free(vc->codebooks[i].codevectors); + ff_free_vlc(&vc->codebooks[i].vlc); + } av_freep(&vc->codebooks); - for (i = 0; i < vc->floor_count; ++i) { - if (vc->floors[i].floor_type == 0) { - av_free(vc->floors[i].data.t0.map[0]); - av_free(vc->floors[i].data.t0.map[1]); - av_free(vc->floors[i].data.t0.book_list); - av_free(vc->floors[i].data.t0.lsp); - } else { - av_free(vc->floors[i].data.t1.list); + if (vc->floors) + for (i = 0; i < vc->floor_count; ++i) { + if (vc->floors[i].floor_type == 0) { + av_free(vc->floors[i].data.t0.map[0]); + av_free(vc->floors[i].data.t0.map[1]); + av_free(vc->floors[i].data.t0.book_list); + av_free(vc->floors[i].data.t0.lsp); + } else { + av_free(vc->floors[i].data.t1.list); + } } - } av_freep(&vc->floors); - for (i = 0; i < vc->mapping_count; ++i) { - av_free(vc->mappings[i].magnitude); - av_free(vc->mappings[i].angle); - av_free(vc->mappings[i].mux); - } + if (vc->mappings) + for (i = 0; i < vc->mapping_count; ++i) { + av_free(vc->mappings[i].magnitude); + av_free(vc->mappings[i].angle); + av_free(vc->mappings[i].mux); + } av_freep(&vc->mappings); } @@ -587,16 +591,24 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) floor_setup->decode = vorbis_floor0_decode; 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); - floor_setup->data.t0.amplitude_bits = get_bits(gb, 6); - /* zero would result in a div by zero later * - * 2^0 - 1 == 0 */ - if (floor_setup->data.t0.amplitude_bits == 0) { + if (!floor_setup->data.t0.order) { av_log(vc->avccontext, AV_LOG_ERROR, - "Floor 0 amplitude bits is 0.\n"); + "Floor 0 order is 0.\n"); return AVERROR_INVALIDDATA; } + floor_setup->data.t0.rate = get_bits(gb, 16); + if (!floor_setup->data.t0.rate) { + av_log(vc->avccontext, AV_LOG_ERROR, + "Floor 0 rate is 0.\n"); + return AVERROR_INVALIDDATA; + } + 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); floor_setup->data.t0.amplitude_offset = get_bits(gb, 8); floor_setup->data.t0.num_books = get_bits(gb, 4) + 1; @@ -1050,6 +1062,9 @@ static int vorbis_floor0_decode(vorbis_context *vc, unsigned amplitude, book_idx; unsigned blockflag = vc->modes[vc->mode_number].blockflag; + if (!vf->amplitude_bits) + return 1; + amplitude = get_bits(&vc->gb, vf->amplitude_bits); if (amplitude > 0) { float last = 0; @@ -1651,6 +1666,45 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, void *data, av_dlog(NULL, "packet length %d \n", buf_size); + if (*buf == 1 && buf_size > 7) { + init_get_bits(gb, buf+1, buf_size*8 - 8); + vorbis_free(vc); + if ((ret = vorbis_parse_id_hdr(vc))) { + av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n"); + vorbis_free(vc); + return ret; + } + + if (vc->audio_channels > 8) + avccontext->channel_layout = 0; + else + avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1]; + + avccontext->channels = vc->audio_channels; + avccontext->sample_rate = vc->audio_samplerate; + return buf_size; + } + + if (*buf == 3 && buf_size > 7) { + av_log(avccontext, AV_LOG_DEBUG, "Ignoring comment header\n"); + return buf_size; + } + + if (*buf == 5 && buf_size > 7 && vc->channel_residues && !vc->modes) { + init_get_bits(gb, buf+1, buf_size*8 - 8); + if ((ret = vorbis_parse_setup_hdr(vc))) { + av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n"); + vorbis_free(vc); + return ret; + } + return buf_size; + } + + if (!vc->channel_residues || !vc->modes) { + av_log(avccontext, AV_LOG_ERROR, "Data packet before valid headers\n"); + return AVERROR_INVALIDDATA; + } + /* get output buffer */ vc->frame.nb_samples = vc->blocksize[1] / 2; if ((ret = ff_get_buffer(avccontext, &vc->frame)) < 0) { diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index d4425bc477..b9c1adbf4d 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -281,15 +281,15 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) Vp3DecodeContext *s = avctx->priv_data; int i; - av_free(s->superblock_coding); - av_free(s->all_fragments); - av_free(s->coded_fragment_list[0]); - av_free(s->dct_tokens_base); - av_free(s->superblock_fragments); - av_free(s->macroblock_coding); - av_free(s->motion_val[0]); - av_free(s->motion_val[1]); - av_free(s->edge_emu_buffer); + av_freep(&s->superblock_coding); + av_freep(&s->all_fragments); + av_freep(&s->coded_fragment_list[0]); + av_freep(&s->dct_tokens_base); + av_freep(&s->superblock_fragments); + av_freep(&s->macroblock_coding); + av_freep(&s->motion_val[0]); + av_freep(&s->motion_val[1]); + av_freep(&s->edge_emu_buffer); if (avctx->internal->is_copy) return 0; @@ -2154,6 +2154,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); } @@ -2339,6 +2343,8 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) } for(i=0;i<3;i++) { + if (header_len[i] <= 0) + continue; init_get_bits(&gb, header_start[i], header_len[i] * 8); ptype = get_bits(&gb, 8); diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index a851fbcf07..e9365180f8 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -40,6 +40,10 @@ static void free_buffers(VP8Context *s) int i; if (s->thread_data) for (i = 0; i < MAX_THREADS; i++) { +#if HAVE_THREADS + pthread_cond_destroy(&s->thread_data[i].cond); + pthread_mutex_destroy(&s->thread_data[i].lock); +#endif av_freep(&s->thread_data[i].filter_strength); av_freep(&s->thread_data[i].edge_emu_buffer); } diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 19b8639c59..c62343eff0 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -135,8 +135,15 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) /* load up the VQA parameters from the header */ s->vqa_version = s->avctx->extradata[0]; - if (s->vqa_version < 1 || s->vqa_version > 3) { - av_log(s->avctx, AV_LOG_ERROR, "unsupported version %d\n", s->vqa_version); + 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(&s->avctx->extradata[6]); @@ -537,6 +544,12 @@ static int vqa_decode_chunk(VqaContext *s) 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 */ bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index], chunk_size); @@ -560,6 +573,12 @@ static int vqa_decode_chunk(VqaContext *s) 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 */ bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index], chunk_size); diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 6b67f30b21..2493089d20 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -26,6 +26,7 @@ #include "get_bits.h" #include "internal.h" #include "unary.h" +#include "bytestream.h" /** * @file @@ -397,6 +398,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, return sign ? ~ret : ret; error: + ret = get_bits_left(gb); + if (ret <= 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "Too few bits (%d) left\n", ret); + } *last = 1; return 0; } @@ -765,12 +770,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, { WavpackContext *wc = avctx->priv_data; WavpackFrameContext *s; + GetByteContext gb; void *samples = data; int samplecount; int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0, got_float = 0, got_hybrid = 0; - const uint8_t *orig_buf = buf; - const uint8_t *buf_end = buf + buf_size; int i, j, id, size, ssize, weights, t; int bpp, chan, chmask, orig_bpp; @@ -781,13 +785,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; } if (wc->ch_offset >= avctx->channels) { @@ -801,20 +805,21 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->and = s->or = s->shift = 0; s->got_extra_bits = 0; + bytestream2_init(&gb, buf, buf_size); + if (!wc->mkv_mode) { - s->samples = AV_RL32(buf); buf += 4; + s->samples = bytestream2_get_le32(&gb); + if (s->samples != wc->samples) + return AVERROR_INVALIDDATA; + if (!s->samples) { *got_frame_ptr = 0; return 0; } - if (s->samples > wc->samples) { - av_log(avctx, AV_LOG_ERROR, "too many samples in block"); - return -1; - } } else { s->samples = wc->samples; } - s->frame_flags = AV_RL32(buf); buf += 4; + s->frame_flags = bytestream2_get_le32(&gb); bpp = av_get_bytes_per_sample(avctx->sample_fmt); samples = (uint8_t*)samples + bpp * wc->ch_offset; orig_bpp = ((s->frame_flags & 0x03) + 1) << 3; @@ -827,19 +832,19 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f); s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1); s->hybrid_minclip = ((-1LL << (orig_bpp - 1))); - s->CRC = AV_RL32(buf); buf += 4; + s->CRC = bytestream2_get_le32(&gb); if (wc->mkv_mode) - buf += 4; //skip block size; + bytestream2_skip(&gb, 4); // skip block size; wc->ch_offset += 1 + s->stereo; // parse metadata blocks - while (buf < buf_end) { - id = *buf++; - size = *buf++; + while (bytestream2_get_bytes_left(&gb)) { + id = bytestream2_get_byte(&gb); + size = bytestream2_get_byte(&gb); if (id & WP_IDF_LONG) { - size |= (*buf++) << 8; - size |= (*buf++) << 16; + size |= (bytestream2_get_byte(&gb)) << 8; + size |= (bytestream2_get_byte(&gb)) << 16; } size <<= 1; // size is specified in words ssize = size; @@ -849,12 +854,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size); break; } - if (buf + ssize > buf_end) { - av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size); + if (bytestream2_get_bytes_left(&gb) < ssize) { + av_log(avctx, AV_LOG_ERROR, + "Block size %i is out of bounds\n", size); break; } if (id & WP_IDF_IGNORE) { - buf += ssize; + bytestream2_skip(&gb, ssize); continue; } switch (id & WP_IDF_MASK) { @@ -862,14 +868,14 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (size > MAX_TERMS) { av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n"); s->terms = 0; - buf += ssize; + bytestream2_skip(&gb, ssize); continue; } s->terms = size; for (i = 0; i < s->terms; i++) { - s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5; - s->decorr[s->terms - i - 1].delta = *buf >> 5; - buf++; + uint8_t val = bytestream2_get_byte(&gb); + s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5; + s->decorr[s->terms - i - 1].delta = val >> 5; } got_terms = 1; break; @@ -881,17 +887,17 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, weights = size >> s->stereo_in; if (weights > MAX_TERMS || weights > s->terms) { av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); - buf += ssize; + bytestream2_skip(&gb, ssize); continue; } for (i = 0; i < weights; i++) { - t = (int8_t)(*buf++); + t = (int8_t)bytestream2_get_byte(&gb); s->decorr[s->terms - i - 1].weightA = t << 3; if (s->decorr[s->terms - i - 1].weightA > 0) s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; if (s->stereo_in) { - t = (int8_t)(*buf++); + t = (int8_t)bytestream2_get_byte(&gb); s->decorr[s->terms - i - 1].weightB = t << 3; if (s->decorr[s->terms - i - 1].weightB > 0) s->decorr[s->terms - i - 1].weightB += @@ -908,23 +914,32 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, t = 0; for (i = s->terms - 1; (i >= 0) && (t < size); i--) { if (s->decorr[i].value > 8) { - s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesA[0] = + wp_exp2(bytestream2_get_le16(&gb)); + s->decorr[i].samplesA[1] = + wp_exp2(bytestream2_get_le16(&gb)); + if (s->stereo_in) { - s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; - t += 4; + s->decorr[i].samplesB[0] = + wp_exp2(bytestream2_get_le16(&gb)); + s->decorr[i].samplesB[1] = + wp_exp2(bytestream2_get_le16(&gb)); + t += 4; } t += 4; } else if (s->decorr[i].value < 0) { - s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; - t += 4; + s->decorr[i].samplesA[0] = + wp_exp2(bytestream2_get_le16(&gb)); + s->decorr[i].samplesB[0] = + wp_exp2(bytestream2_get_le16(&gb)); + t += 4; } else { for (j = 0; j < s->decorr[i].value; j++) { - s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesA[j] = + wp_exp2(bytestream2_get_le16(&gb)); if (s->stereo_in) { - s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesB[j] = + wp_exp2(bytestream2_get_le16(&gb)); } } t += s->decorr[i].value * 2 * (s->stereo_in + 1); @@ -934,15 +949,15 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, break; case WP_ID_ENTROPY: if (size != 6 * (s->stereo_in + 1)) { - av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, " - "got %i", 6 * (s->stereo_in + 1), size); - buf += ssize; + av_log(avctx, AV_LOG_ERROR, + "Entropy vars size should be %i, got %i", + 6 * (s->stereo_in + 1), size); + bytestream2_skip(&gb, ssize); continue; } for (j = 0; j <= s->stereo_in; j++) { for (i = 0; i < 3; i++) { - s->ch[j].median[i] = wp_exp2(AV_RL16(buf)); - buf += 2; + s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb)); } } got_entropy = 1; @@ -950,20 +965,18 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_HYBRID: if (s->hybrid_bitrate) { for (i = 0; i <= s->stereo_in; i++) { - s->ch[i].slow_level = wp_exp2(AV_RL16(buf)); - buf += 2; - size -= 2; + s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb)); + size -= 2; } } for (i = 0; i < (s->stereo_in + 1); i++) { - s->ch[i].bitrate_acc = AV_RL16(buf) << 16; - buf += 2; - size -= 2; + s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16; + size -= 2; } if (size > 0) { for (i = 0; i < (s->stereo_in + 1); i++) { - s->ch[i].bitrate_delta = wp_exp2((int16_t)AV_RL16(buf)); - buf += 2; + s->ch[i].bitrate_delta = + wp_exp2((int16_t)bytestream2_get_le16(&gb)); } } else { for (i = 0; i < (s->stereo_in + 1); i++) @@ -971,22 +984,26 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } got_hybrid = 1; break; - case WP_ID_INT32INFO: + case WP_ID_INT32INFO: { + uint8_t val[4]; if (size != 4) { - av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf); - buf += ssize; + av_log(avctx, AV_LOG_ERROR, + "Invalid INT32INFO, size = %i\n", + size); + bytestream2_skip(&gb, ssize - 4); continue; } - if (buf[0]) - s->extra_bits = buf[0]; - else if (buf[1]) - s->shift = buf[1]; - else if (buf[2]){ - s->and = s->or = 1; - s->shift = buf[2]; - } else if(buf[3]) { + bytestream2_get_buffer(&gb, val, 4); + if (val[0]) { + s->extra_bits = val[0]; + } else if (val[1]) { + s->shift = val[1]; + } else if (val[2]) { + s->and = s->or = 1; + s->shift = val[2]; + } else if (val[3]) { s->and = 1; - s->shift = buf[3]; + s->shift = val[3]; } /* original WavPack decoder forces 32-bit lossy sound to be treated * as 24-bit one in order to have proper clipping @@ -997,56 +1014,66 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->hybrid_maxclip >>= 8; s->hybrid_minclip >>= 8; } - buf += 4; break; + } case WP_ID_FLOATINFO: if (size != 4) { - av_log(avctx, AV_LOG_ERROR, "Invalid FLOATINFO, size = %i\n", size); - buf += ssize; + av_log(avctx, AV_LOG_ERROR, + "Invalid FLOATINFO, size = %i\n", size); + bytestream2_skip(&gb, ssize); continue; } - s->float_flag = buf[0]; - s->float_shift = buf[1]; - s->float_max_exp = buf[2]; - buf += 4; - got_float = 1; + s->float_flag = bytestream2_get_byte(&gb); + s->float_shift = bytestream2_get_byte(&gb); + s->float_max_exp = bytestream2_get_byte(&gb); + got_float = 1; + bytestream2_skip(&gb, 1); break; case WP_ID_DATA: - s->sc.offset = buf - orig_buf; + s->sc.offset = bytestream2_tell(&gb); s->sc.size = size * 8; - init_get_bits(&s->gb, buf, size * 8); + init_get_bits(&s->gb, gb.buffer, size * 8); s->data_size = size * 8; - buf += size; + bytestream2_skip(&gb, size); got_bs = 1; break; case WP_ID_EXTRABITS: if (size <= 4) { av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n", size); - buf += size; + bytestream2_skip(&gb, size); continue; } - s->extra_sc.offset = buf - orig_buf; + s->extra_sc.offset = bytestream2_tell(&gb); s->extra_sc.size = size * 8; - init_get_bits(&s->gb_extra_bits, buf, size * 8); - s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32); - buf += size; - s->got_extra_bits = 1; + init_get_bits(&s->gb_extra_bits, gb.buffer, size * 8); + s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32); + bytestream2_skip(&gb, size); + s->got_extra_bits = 1; break; case WP_ID_CHANINFO: if (size <= 1) { av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n"); - return -1; + return AVERROR_INVALIDDATA; } - chan = *buf++; + chan = bytestream2_get_byte(&gb); switch (size - 2) { - case 0: chmask = *buf; break; - case 1: chmask = AV_RL16(buf); break; - case 2: chmask = AV_RL24(buf); break; - case 3: chmask = AV_RL32(buf); break; + case 0: + chmask = bytestream2_get_byte(&gb); + break; + case 1: + chmask = bytestream2_get_le16(&gb); + break; + case 2: + chmask = bytestream2_get_le24(&gb); + break; + case 3: + chmask = bytestream2_get_le32(&gb); + break; case 5: - chan |= (buf[1] & 0xF) << 8; - chmask = AV_RL24(buf + 2); + bytestream2_skip(&gb, 1); + chan |= (bytestream2_get_byte(&gb) & 0xF) << 8; + chmask = bytestream2_get_le16(&gb); break; default: av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n", @@ -1055,49 +1082,49 @@ 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; - buf += size - 1; break; default: - buf += size; + bytestream2_skip(&gb, size); } if (id & WP_IDF_ODD) - buf++; + bytestream2_skip(&gb, 1); } 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); @@ -1117,7 +1144,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 { @@ -1131,7 +1158,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; @@ -1186,6 +1213,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; @@ -1205,7 +1235,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } if (frame_flags & 0x80) { @@ -1247,7 +1277,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, s->frame.data[0], got_frame_ptr, buf, frame_size)) < 0) { wavpack_decode_flush(avctx); - return AVERROR_INVALIDDATA; + return samplecount; } s->block++; buf += frame_size; buf_size -= frame_size; diff --git a/libavcodec/wma.c b/libavcodec/wma.c index d0c0b34868..3aefd5eabf 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -382,9 +382,9 @@ int ff_wma_end(AVCodecContext *avctx) } for (i = 0; i < 2; i++) { ff_free_vlc(&s->coef_vlc[i]); - av_free(s->run_table[i]); - av_free(s->level_table[i]); - av_free(s->int_table[i]); + av_freep(&s->run_table[i]); + av_freep(&s->level_table[i]); + av_freep(&s->int_table[i]); } return 0; diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 48d52fdc05..7de87dbcd8 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -72,6 +72,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 */ @@ -509,6 +514,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) diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 4f372619ee..8d56ea0594 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -127,8 +127,8 @@ typedef struct WmallDecodeCtx { int8_t mclms_order; int8_t mclms_scaling; - int16_t mclms_coeffs[128]; - int16_t mclms_coeffs_cur[4]; + int16_t mclms_coeffs[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS * 32]; + int16_t mclms_coeffs_cur[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS]; int16_t mclms_prevvalues[WMALL_MAX_CHANNELS * 2 * 32]; int16_t mclms_updates[WMALL_MAX_CHANNELS * 2 * 32]; int mclms_recent; diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 41e07aa5f8..ce92c7f88a 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -107,6 +107,7 @@ #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MAX_BITS 13 ///< 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 +281,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; ff_dsputil_init(&s->dsp, avctx); avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); @@ -335,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - if (s->min_samples_per_subframe < (1<min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) { av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n", s->min_samples_per_subframe); return AVERROR_INVALIDDATA; @@ -413,6 +419,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; @@ -437,7 +446,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; } } @@ -727,6 +737,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; @@ -1129,11 +1140,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; @@ -1189,6 +1201,7 @@ static int decode_subframe(WMAProDecodeCtx *s) 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 { @@ -1470,6 +1483,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), @@ -1515,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 0ae3748911..02e14be92a 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1050,9 +1050,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; @@ -1114,7 +1115,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))) { @@ -1131,6 +1132,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; } /** @@ -1293,7 +1295,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; diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index c59ceb7f1d..1f4ca1af85 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -71,8 +71,8 @@ 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); + if (buf_size <= 8) { + av_log(avctx, AV_LOG_ERROR, "Packet size %d is too small\n", buf_size); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm index 4958a7b67e..4a93107282 100644 --- a/libavcodec/x86/ac3dsp.asm +++ b/libavcodec/x86/ac3dsp.asm @@ -382,42 +382,6 @@ cglobal ac3_compute_mantissa_size, 1, 2, 4, mant_cnt, sum %endif %endmacro -%if HAVE_AMD3DNOW_EXTERNAL -INIT_MMX 3dnow -cglobal ac3_extract_exponents, 3, 3, 0, exp, coef, len - add expq, lenq - lea coefq, [coefq+4*lenq] - neg lenq - movq m3, [pd_1] - movq m4, [pd_151] -.loop: - movq m0, [coefq+4*lenq ] - movq m1, [coefq+4*lenq+8] - PABSD m0, m2 - PABSD m1, m2 - pslld m0, 1 - por m0, m3 - pi2fd m2, m0 - psrld m2, 23 - movq m0, m4 - psubd m0, m2 - pslld m1, 1 - por m1, m3 - pi2fd m2, m1 - psrld m2, 23 - movq m1, m4 - psubd m1, m2 - packssdw m0, m0 - packuswb m0, m0 - packssdw m1, m1 - packuswb m1, m1 - punpcklwd m0, m1 - movd [expq+lenq], m0 - add lenq, 4 - jl .loop - REP_RET -%endif - %macro AC3_EXTRACT_EXPONENTS 0 cglobal ac3_extract_exponents, 3, 3, 4, exp, coef, len add expq, lenq diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c index e2a190e07c..01127fce40 100644 --- a/libavcodec/x86/ac3dsp_init.c +++ b/libavcodec/x86/ac3dsp_init.c @@ -194,7 +194,6 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx; } if (EXTERNAL_AMD3DNOW(mm_flags)) { - c->extract_exponents = ff_ac3_extract_exponents_3dnow; if (!bit_exact) { c->float_to_fixed24 = ff_float_to_fixed24_3dnow; } diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index f820d1f0d4..96abaf90bc 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -1785,6 +1785,7 @@ static av_always_inline void gmc(uint8_t *dst, uint8_t *src, } } +#if CONFIG_VIDEODSP #if HAVE_YASM #if ARCH_X86_32 static void gmc_mmx(uint8_t *dst, uint8_t *src, @@ -1814,6 +1815,7 @@ static void gmc_mmx(uint8_t *dst, uint8_t *src, width, height, &ff_emulated_edge_mc_8); } #endif +#endif #endif /* HAVE_INLINE_ASM */ @@ -2518,7 +2520,7 @@ static void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, int mm_flags) c->scalarproduct_float = ff_scalarproduct_float_sse; c->butterflies_float_interleave = ff_butterflies_float_interleave_sse; -#if HAVE_INLINE_ASM +#if HAVE_INLINE_ASM && CONFIG_VIDEODSP c->gmc = gmc_sse; #endif #endif /* HAVE_YASM */ @@ -2531,7 +2533,7 @@ static void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx, const int high_bit_depth = bit_depth > 8; #if HAVE_SSE2_INLINE - if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) { + if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX && avctx->lowres == 0) { c->idct_put = ff_idct_xvid_sse2_put; c->idct_add = ff_idct_xvid_sse2_add; c->idct = ff_idct_xvid_sse2; diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm index 8ac38fcaa8..5f2374d3ea 100644 --- a/libavcodec/x86/h264_deblock.asm +++ b/libavcodec/x86/h264_deblock.asm @@ -625,7 +625,11 @@ DEBLOCK_LUMA v, 16 %define t5 m11 %define mask0 m12 %define mask1p m13 +%if WIN64 + %define mask1q [rsp] +%else %define mask1q [rsp-24] +%endif %define mpb_0 m14 %define mpb_1 m15 %else @@ -644,7 +648,11 @@ DEBLOCK_LUMA v, 16 ;----------------------------------------------------------------------------- ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta ) ;----------------------------------------------------------------------------- +%if WIN64 +cglobal deblock_%1_luma_intra_8, 4,6,16,0x10 +%else cglobal deblock_%1_luma_intra_8, 4,6,16,ARCH_X86_64*0x50-0x50 +%endif lea r4, [r1*4] lea r5, [r1*3] ; 3*stride dec r2d ; alpha-1 diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c index deededaddb..006b6573d9 100644 --- a/libavcodec/x86/h264_intrapred_init.c +++ b/libavcodec/x86/h264_intrapred_init.c @@ -187,7 +187,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth if (EXTERNAL_MMX(mm_flags)) { h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmx; h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmx; - if (chroma_format_idc == 1) { + if (chroma_format_idc <= 1) { h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_8_mmx; h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmx; } @@ -196,7 +196,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_mmx; h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_mmx; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmx; if (codec_id == AV_CODEC_ID_SVQ3) { if (mm_flags & AV_CPU_FLAG_CMOV) @@ -212,7 +212,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth if (EXTERNAL_MMXEXT(mm_flags)) { h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmxext; h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmxext; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmxext; h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_mmxext; h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_mmxext; @@ -237,7 +237,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_8_mmxext; } if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { - if (chroma_format_idc == 1) { + if (chroma_format_idc <= 1) { h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_8_mmxext; h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_8_mmxext; } @@ -249,7 +249,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_8_mmxext; h->pred4x4 [VERT_PRED ] = ff_pred4x4_vertical_vp8_8_mmxext; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmxext; if (codec_id == AV_CODEC_ID_SVQ3) { h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_8_mmxext; @@ -276,7 +276,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_sse2; h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_sse2; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_sse2; if (codec_id == AV_CODEC_ID_SVQ3) { h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_sse2; @@ -291,7 +291,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth if (EXTERNAL_SSSE3(mm_flags)) { h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_ssse3; h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_ssse3; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_ssse3; h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_ssse3; h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_ssse3; @@ -307,7 +307,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_ssse3; h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_ssse3; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_ssse3; if (codec_id == AV_CODEC_ID_SVQ3) { h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_ssse3; @@ -323,7 +323,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; @@ -342,7 +342,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/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c index 65d300fe4d..10f8dab88b 100644 --- a/libavcodec/x86/h264dsp_init.c +++ b/libavcodec/x86/h264dsp_init.c @@ -213,7 +213,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, #if HAVE_YASM int mm_flags = av_get_cpu_flags(); - if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(mm_flags)) + if (chroma_format_idc <= 1 && EXTERNAL_MMXEXT(mm_flags)) c->h264_loop_filter_strength = ff_h264_loop_filter_strength_mmxext; if (bit_depth == 8) { @@ -225,7 +225,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, 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; if (mm_flags & AV_CPU_FLAG_CMOV) @@ -236,13 +236,13 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext; c->h264_idct_add16 = ff_h264_idct_add16_8_mmxext; c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmxext; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext; c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext; 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; } @@ -265,7 +265,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, 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; @@ -310,7 +310,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, 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 @@ -350,7 +350,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, 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/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c index d121b25031..bb424eed6f 100644 --- a/libavcodec/x86/idct_sse2_xvid.c +++ b/libavcodec/x86/idct_sse2_xvid.c @@ -344,7 +344,7 @@ DECLARE_ASM_CONST(16, int32_t, walkenIdctRounders)[] = { "movdqa %%xmm6, 4*16("dct") \n\t" \ "movdqa "SREG2", 7*16("dct") \n\t" -inline void ff_idct_xvid_sse2(short *block) +av_extern_inline void ff_idct_xvid_sse2(short *block) { __asm__ volatile( "movq "MANGLE(m127)", %%mm0 \n\t" diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h index 79e29e6232..76ea1315c2 100644 --- a/libavcodec/x86/mathops.h +++ b/libavcodec/x86/mathops.h @@ -74,7 +74,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/mlpdsp.c b/libavcodec/x86/mlpdsp.c index de28e22b52..5541b287ba 100644 --- a/libavcodec/x86/mlpdsp.c +++ b/libavcodec/x86/mlpdsp.c @@ -129,8 +129,8 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, FIRMUL (ff_mlp_firorder_6, 0x14 ) FIRMUL (ff_mlp_firorder_5, 0x10 ) FIRMUL (ff_mlp_firorder_4, 0x0c ) - FIRMULREG(ff_mlp_firorder_3, 0x08,10) - FIRMULREG(ff_mlp_firorder_2, 0x04, 9) + FIRMUL (ff_mlp_firorder_3, 0x08 ) + FIRMUL (ff_mlp_firorder_2, 0x04 ) FIRMULREG(ff_mlp_firorder_1, 0x00, 8) LABEL_MANGLE(ff_mlp_firorder_0)":\n\t" "jmp *%6 \n\t" @@ -159,8 +159,6 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, : /* 4*/"r"((x86_reg)mask), /* 5*/"r"(firjump), /* 6*/"r"(iirjump) , /* 7*/"c"(filter_shift) , /* 8*/"r"((int64_t)coeff[0]) - , /* 9*/"r"((int64_t)coeff[1]) - , /*10*/"r"((int64_t)coeff[2]) : "rax", "rdx", "rsi" #else /* ARCH_X86_32 */ /* 3*/"+m"(blocksize) diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c index 9870ed7d51..2ca661c69a 100644 --- a/libavcodec/x86/mpegvideo.c +++ b/libavcodec/x86/mpegvideo.c @@ -26,7 +26,7 @@ #include "libavcodec/mpegvideo.h" #include "dsputil_mmx.h" -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, DCTELEM *block, int n, int qscale) @@ -574,11 +574,11 @@ static void denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){ ); } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ void ff_MPV_common_init_x86(MpegEncContext *s) { -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE int mm_flags = av_get_cpu_flags(); if (mm_flags & AV_CPU_FLAG_MMX) { @@ -596,5 +596,5 @@ void ff_MPV_common_init_x86(MpegEncContext *s) s->denoise_dct= denoise_dct_mmx; } } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ } diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c index 47c3b43f94..2506ba0fe3 100644 --- a/libavcodec/x86/mpegvideoenc_template.c +++ b/libavcodec/x86/mpegvideoenc_template.c @@ -216,7 +216,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, "psubusw "MM"1, "MM"4 \n\t" "packuswb "MM"4, "MM"4 \n\t" #if COMPILE_TEMPLATE_SSE2 - "packuswb "MM"4, "MM"4 \n\t" + "packsswb "MM"4, "MM"4 \n\t" #endif "movd "MM"4, %0 \n\t" // *overflow : "=g" (*overflow) diff --git a/libavcodec/x86/videodsp_init.c b/libavcodec/x86/videodsp_init.c index 4a8b244254..bbf9464d8d 100644 --- a/libavcodec/x86/videodsp_init.c +++ b/libavcodec/x86/videodsp_init.c @@ -44,7 +44,7 @@ static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src, emu_edge_core_func *core_fn) { int start_y, start_x, end_y, end_x, src_y_add = 0; - int linesize = linesize_arg; + emuedge_linesize_type linesize = linesize_arg; if(!w || !h) return; diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 899c1f1d22..9ab3270f6e 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -106,6 +106,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 +122,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 +277,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,10 +286,9 @@ 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; - const unsigned char *buf_end = s->buf + s->size; int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size; @@ -307,13 +307,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, @@ -360,31 +361,29 @@ static int xan_wc3_decode_frame(XanContext *s) { case 9: case 19: - if (buf_end - size_segment < 1) { + if (bytestream2_get_bytes_left(&size_segment) < 1) { av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n"); return AVERROR_INVALIDDATA; } - size = *size_segment++; + size = bytestream2_get_byte(&size_segment); break; case 10: case 20: - if (buf_end - size_segment < 2) { + if (bytestream2_get_bytes_left(&size_segment) < 2) { av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n"); return AVERROR_INVALIDDATA; } - size = AV_RB16(&size_segment[0]); - size_segment += 2; + size = bytestream2_get_be16(&size_segment); break; case 11: case 21: - if (buf_end - size_segment < 3) { + if (bytestream2_get_bytes_left(&size_segment) < 3) { av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n"); return AVERROR_INVALIDDATA; } - size = AV_RB24(size_segment); - size_segment += 3; + size = bytestream2_get_be24(&size_segment); break; } @@ -405,14 +404,15 @@ static int xan_wc3_decode_frame(XanContext *s) { imagedata_size -= size; } } else { - if (vector_segment >= buf_end) { + uint8_t vector; + if (bytestream2_get_bytes_left(&vector_segment) <= 0) { av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n"); return AVERROR_INVALIDDATA; } /* 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++; + 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); diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c index 2a41836492..5166c4e6ed 100644 --- a/libavcodec/xbmdec.c +++ b/libavcodec/xbmdec.c @@ -58,7 +58,7 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data, int number, len; ptr += strcspn(ptr, "#"); - if (sscanf(ptr, "#define %256s %u", name, &number) != 2) { + if (sscanf(ptr, "#define %255s %u", name, &number) != 2) { av_log(avctx, AV_LOG_ERROR, "Unexpected preprocessor directive\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index ed1821772f..c8ccb9716c 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -45,6 +45,15 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV420P; + if (avctx->height < 8) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame height: %d.\n", avctx->height); + return AVERROR(EINVAL); + } + 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) @@ -212,6 +221,10 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) U += s->pic.linesize[1]; V += s->pic.linesize[2]; } + if (avctx->height & 1) { + memcpy(U, U - s->pic.linesize[1], avctx->width >> 1); + memcpy(V, V - s->pic.linesize[2], avctx->width >> 1); + } } else { uint8_t *U2 = U + s->pic.linesize[1]; uint8_t *V2 = V + s->pic.linesize[2]; @@ -236,6 +249,12 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) U2 += s->pic.linesize[1] * 2; V2 += s->pic.linesize[2] * 2; } + if (avctx->height & 3) { + int lines = ((avctx->height + 1) >> 1) - (avctx->height >> 2) * 2; + + memcpy(U, U - lines * s->pic.linesize[1], lines * s->pic.linesize[1]); + memcpy(V, V - lines * s->pic.linesize[2], lines * s->pic.linesize[2]); + } } return 0; @@ -300,7 +319,7 @@ static int xan_decode_frame_type0(AVCodecContext *avctx) int dec_size; bytestream2_seek(&s->gb, 8 + corr_off, SEEK_SET); - dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size); + dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size / 2); if (dec_size < 0) dec_size = 0; else diff --git a/libavcodec/yop.c b/libavcodec/yop.c index 337fb88365..1db567f456 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -39,6 +39,7 @@ typedef struct YopDecContext { uint8_t *low_nibble; uint8_t *srcptr; + uint8_t *src_end; uint8_t *dstptr; uint8_t *dstbuf; } YopDecContext; @@ -88,8 +89,8 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) return -1; } - if (!avctx->extradata) { - av_log(avctx, AV_LOG_ERROR, "extradata missing\n"); + if (avctx->extradata_size < 3) { + av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata.\n"); return AVERROR_INVALIDDATA; } @@ -123,8 +124,13 @@ static av_cold int yop_decode_close(AVCodecContext *avctx) * @param s codec context * @param tag the tag that was in the nibble */ -static void yop_paint_block(YopDecContext *s, int tag) +static int yop_paint_block(YopDecContext *s, int tag) { + if (s->src_end - s->srcptr < paint_lut[tag][3]) { + av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n"); + return AVERROR_INVALIDDATA; + } + s->dstptr[0] = s->srcptr[0]; s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]]; @@ -132,6 +138,7 @@ static void yop_paint_block(YopDecContext *s, int tag) // The number of src bytes consumed is in the last part of the lut entry. s->srcptr += paint_lut[tag][3]; + return 0; } /** @@ -184,6 +191,11 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int ret, i, x, y; uint32_t *palette; + if (avpkt->size < 4 + 3 * s->num_pal_colors) { + av_log(avctx, AV_LOG_ERROR, "Packet too small.\n"); + return AVERROR_INVALIDDATA; + } + if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); @@ -201,6 +213,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->dstbuf = s->frame.data[0]; s->dstptr = s->frame.data[0]; s->srcptr = avpkt->data + 4; + s->src_end = avpkt->data + avpkt->size; s->low_nibble = NULL; is_odd_frame = avpkt->data[0]; @@ -231,7 +244,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, tag = yop_get_next_nibble(s); if (tag != 0xf) { - yop_paint_block(s, tag); + ret = yop_paint_block(s, tag); + if (ret < 0) + return ret; } else { tag = yop_get_next_nibble(s); ret = yop_copy_previous_block(s, tag); diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index 83743c52a2..c9bfcd2751 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -418,17 +418,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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]; c->fmt = buf[3]; c->bw = buf[4]; c->bh = buf[5]; + c->decode_intra = NULL; + c->decode_xor = NULL; buf += 6; len -= 6; @@ -506,7 +513,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac if (c->comp == 0) { //Uncompressed data if (c->decomp_size < len) { - av_log(avctx, AV_LOG_ERROR, "decomp buffer too small\n"); + av_log(avctx, AV_LOG_ERROR, "Buffer too small\n"); return AVERROR_INVALIDDATA; } memcpy(c->decomp_buf, buf, len); diff --git a/libavdevice/libcdio.c b/libavdevice/libcdio.c index ec53e2c072..a824bc3882 100644 --- a/libavdevice/libcdio.c +++ b/libavdevice/libcdio.c @@ -23,8 +23,15 @@ * libcdio CD grabbing */ +#include "config.h" + +#if HAVE_CDIO_PARANOIA_H #include #include +#elif HAVE_CDIO_PARANOIA_PARANOIA_H +#include +#include +#endif #include "libavutil/log.h" #include "libavutil/mem.h" diff --git a/libavdevice/pulse.c b/libavdevice/pulse.c index 86fdc22837..904aeffe70 100644 --- a/libavdevice/pulse.c +++ b/libavdevice/pulse.c @@ -31,6 +31,7 @@ #include "libavformat/avformat.h" #include "libavformat/internal.h" +#include "libavutil/time.h" #include "libavutil/opt.h" #define DEFAULT_CODEC_ID AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE) @@ -47,6 +48,7 @@ typedef struct PulseData { pa_simple *s; int64_t pts; int64_t frame_duration; + int wallclock; } PulseData; static pa_sample_format_t codec_id_to_pulse_format(int codec_id) { @@ -141,6 +143,8 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) if (pd->pts == AV_NOPTS_VALUE) { pd->pts = -latency; + if (pd->wallclock) + pd->pts += av_gettime(); } pkt->pts = pd->pts; @@ -168,6 +172,7 @@ static const AVOption options[] = { { "channels", "number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, D }, { "frame_size", "number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, D }, { "fragment_size", "buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D }, + { "wallclock", "set the initial pts using the current time", OFFSET(wallclock), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, D }, { NULL }, }; diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index b2e5fed27d..002329e14e 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -495,16 +495,18 @@ static int init_convert_timestamp(AVFormatContext *ctx, int64_t ts) return 0; } #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) - now = av_gettime_monotonic(); - if (s->ts_mode == V4L_TS_MONO2ABS || - (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE)) { - int64_t period = av_rescale_q(1, ctx->streams[0]->codec->time_base, - AV_TIME_BASE_Q); - av_log(ctx, AV_LOG_INFO, "Detected monotonic timestamps, converting\n"); - /* microseconds instead of seconds, MHz instead of Hz */ - s->timefilter = ff_timefilter_new(1, period, 1.0E-6); - s->ts_mode = V4L_TS_CONVERT_READY; - return 0; + if (ctx->streams[0]->codec->time_base.den) { + now = av_gettime_monotonic(); + if (s->ts_mode == V4L_TS_MONO2ABS || + (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE)) { + int64_t period = av_rescale_q(1, ctx->streams[0]->codec->time_base, + AV_TIME_BASE_Q); + av_log(ctx, AV_LOG_INFO, "Detected monotonic timestamps, converting\n"); + /* microseconds instead of seconds, MHz instead of Hz */ + s->timefilter = ff_timefilter_new(1, period, 1.0E-6); + s->ts_mode = V4L_TS_CONVERT_READY; + return 0; + } } #endif av_log(ctx, AV_LOG_ERROR, "Unknown timestamps\n"); @@ -735,8 +737,11 @@ static int v4l2_set_parameters(AVFormatContext *s1) return AVERROR(errno); } } - s1->streams[0]->codec->time_base.den = tpf->denominator; - s1->streams[0]->codec->time_base.num = tpf->numerator; + if (tpf->denominator > 0 && tpf->numerator > 0) { + s1->streams[0]->codec->time_base.den = tpf->denominator; + s1->streams[0]->codec->time_base.num = tpf->numerator; + } else + av_log(s1, AV_LOG_WARNING, "Time per frame unknown\n"); return 0; } @@ -882,11 +887,15 @@ static int v4l2_read_header(AVFormatContext *s1) if (codec_id == AV_CODEC_ID_RAWVIDEO) st->codec->codec_tag = avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt); + else if (codec_id == AV_CODEC_ID_H264) { + st->need_parsing = AVSTREAM_PARSE_HEADERS; + } if (desired_format == V4L2_PIX_FMT_YVU420) st->codec->codec_tag = MKTAG('Y', 'V', '1', '2'); st->codec->width = s->width; st->codec->height = s->height; - st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; + if (st->codec->time_base.num) + st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; out: return res; diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c index 612400654b..7db1da675a 100644 --- a/libavdevice/x11grab.c +++ b/libavdevice/x11grab.c @@ -78,6 +78,7 @@ struct x11grab { int show_region; /**< set by a private option. */ char *framerate; /**< Set by a private option. */ + Cursor c; Window region_win; /**< This is used by show_region option. */ }; @@ -353,7 +354,6 @@ paint_mouse_pointer(XImage *image, struct x11grab *s) * Anyone who performs further investigation of the xlib API likely risks * permanent brain damage. */ uint8_t *pix = image->data; - Cursor c; Window w; XSetWindowAttributes attr; @@ -361,9 +361,10 @@ paint_mouse_pointer(XImage *image, struct x11grab *s) if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32) return; - c = XCreateFontCursor(dpy, XC_left_ptr); + if(!s->c) + s->c = XCreateFontCursor(dpy, XC_left_ptr); w = DefaultRootWindow(dpy); - attr.cursor = c; + attr.cursor = s->c; XChangeWindowAttributes(dpy, w, CWCursor, &attr); xcim = XFixesGetCursorImage(dpy); diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c index 500be0f73a..415beaa487 100644 --- a/libavfilter/af_asyncts.c +++ b/libavfilter/af_asyncts.c @@ -231,18 +231,23 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf) } if (s->first_frame && delta > 0) { + int planar = av_sample_fmt_is_planar(buf_out->format); + int planes = planar ? nb_channels : 1; + int block_size = av_get_bytes_per_sample(buf_out->format) * + (planar ? 1 : nb_channels); + int ch; av_samples_set_silence(buf_out->extended_data, 0, delta, nb_channels, buf->format); - for (ch = 0; ch < nb_channels; ch++) - buf_out->extended_data[ch] += delta; + for (ch = 0; ch < planes; ch++) + buf_out->extended_data[ch] += delta * block_size; avresample_read(s->avr, buf_out->extended_data, out_size); - for (ch = 0; ch < nb_channels; ch++) - buf_out->extended_data[ch] -= delta; + for (ch = 0; ch < planes; ch++) + buf_out->extended_data[ch] -= delta * block_size; } else { avresample_read(s->avr, buf_out->extended_data, out_size); diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c index 6fe8704694..398b3dd0e5 100644 --- a/libavfilter/af_channelmap.c +++ b/libavfilter/af_channelmap.c @@ -196,7 +196,7 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args) s->map[i].out_channel_idx = i; break; case MAP_ONE_STR: - if (!get_channel(&mapping, &in_ch, ',')) { + if (get_channel(&mapping, &in_ch, ',') < 0) { av_log(ctx, AV_LOG_ERROR, err); ret = AVERROR(EINVAL); goto fail; @@ -361,23 +361,32 @@ static int channelmap_config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; ChannelMapContext *s = ctx->priv; + int nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout); int i, err = 0; const char *channel_name; char layout_name[256]; - if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) { - for (i = 0; i < s->nch; i++) { + for (i = 0; i < s->nch; i++) { + if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) { s->map[i].in_channel_idx = av_get_channel_layout_channel_index( inlink->channel_layout, s->map[i].in_channel); - if (s->map[i].in_channel_idx < 0) { + } + + if (s->map[i].in_channel_idx < 0 || + s->map[i].in_channel_idx >= nb_channels) { + av_get_channel_layout_string(layout_name, sizeof(layout_name), + 0, inlink->channel_layout); + if (s->map[i].in_channel) { channel_name = av_get_channel_name(s->map[i].in_channel); - av_get_channel_layout_string(layout_name, sizeof(layout_name), - 0, inlink->channel_layout); av_log(ctx, AV_LOG_ERROR, "input channel '%s' not available from input layout '%s'\n", channel_name, layout_name); - err = AVERROR(EINVAL); + } else { + av_log(ctx, AV_LOG_ERROR, + "input channel #%d not available from input layout '%s'\n", + s->map[i].in_channel_idx, layout_name); } + err = AVERROR(EINVAL); } } diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c index 5ffa1fea4f..688cca5531 100644 --- a/libavfilter/af_volume.c +++ b/libavfilter/af_volume.c @@ -275,6 +275,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf) } } + emms_c(); + if (buf != out_buf) avfilter_unref_buffer(buf); diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 4edd5be30f..b21e1ad07f 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -117,9 +117,9 @@ void ff_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 c05bbb7fe6..471a8e6779 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -24,6 +24,7 @@ #include #include "libavutil/avassert.h" +#include "libavutil/avstring.h" #include "libavutil/channel_layout.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -373,11 +374,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d", scaler_count++); - if (graph->scale_sws_opts) - snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts); - else - snprintf(scale_args, sizeof(scale_args), "0:0"); - + av_strlcpy(scale_args, "0:0", sizeof(scale_args)); + if (graph->scale_sws_opts) { + av_strlcat(scale_args, ":", sizeof(scale_args)); + av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args)); + } if ((ret = avfilter_graph_create_filter(&convert, filter, inst_name, scale_args, NULL, graph)) < 0) diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index 4881a85ece..02a6a92c61 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -298,13 +298,6 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *ref) } 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 key:%d", - (int)select->var_values[VAR_N], - (int)select->var_values[VAR_PTS], - select->var_values[VAR_T], - (int)select->var_values[VAR_POS], - (int)select->var_values[VAR_KEY]); switch (inlink->type) { case AVMEDIA_TYPE_VIDEO: diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index 9597fb3255..b0894e7e2f 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -184,8 +184,25 @@ static int return_audio_frame(AVFilterContext *ctx) } while (s->buf_out->audio->nb_samples < s->allocated_samples) { - int len = FFMIN(s->allocated_samples - s->buf_out->audio->nb_samples, - head->audio->nb_samples); + int len; + + if (!s->root.next && + (ret = ff_request_frame(ctx->inputs[0])) < 0) { + if (ret == AVERROR_EOF) { + av_samples_set_silence(s->buf_out->extended_data, + s->buf_out->audio->nb_samples, + s->allocated_samples - + s->buf_out->audio->nb_samples, + nb_channels, link->format); + s->buf_out->audio->nb_samples = s->allocated_samples; + break; + } + return ret; + } + head = s->root.next->buf; + + len = FFMIN(s->allocated_samples - s->buf_out->audio->nb_samples, + head->audio->nb_samples); av_samples_copy(s->buf_out->extended_data, head->extended_data, s->buf_out->audio->nb_samples, 0, len, nb_channels, @@ -195,21 +212,6 @@ static int return_audio_frame(AVFilterContext *ctx) if (len == head->audio->nb_samples) { avfilter_unref_buffer(head); queue_pop(s); - - if (!s->root.next && - (ret = ff_request_frame(ctx->inputs[0])) < 0) { - if (ret == AVERROR_EOF) { - av_samples_set_silence(s->buf_out->extended_data, - s->buf_out->audio->nb_samples, - s->allocated_samples - - s->buf_out->audio->nb_samples, - nb_channels, link->format); - s->buf_out->audio->nb_samples = s->allocated_samples; - break; - } - return ret; - } - head = s->root.next->buf; } else { buffer_offset(link, head, len); } diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c index 72867292a9..789d10d724 100644 --- a/libavfilter/filtfmts.c +++ b/libavfilter/filtfmts.c @@ -38,7 +38,7 @@ static void print_formats(AVFilterContext *filter_ctx) for (j = 0; j < fmts->format_count; j++) \ if(av_get_pix_fmt_name(fmts->formats[j])) \ printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ + i, filter_ctx->inout##put_pads[i].name, \ av_get_pix_fmt_name(fmts->formats[j])); \ } else if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_AUDIO) { \ AVFilterFormats *fmts; \ @@ -47,7 +47,7 @@ static void print_formats(AVFilterContext *filter_ctx) fmts = filter_ctx->inout##puts[i]->outin##_formats; \ for (j = 0; j < fmts->format_count; j++) \ printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ + i, filter_ctx->inout##put_pads[i].name, \ av_get_sample_fmt_name(fmts->formats[j])); \ \ layouts = filter_ctx->inout##puts[i]->outin##_channel_layouts; \ @@ -56,7 +56,7 @@ static void print_formats(AVFilterContext *filter_ctx) av_get_channel_layout_string(buf, sizeof(buf), -1, \ layouts->channel_layouts[j]); \ printf(#INOUT "PUT[%d] %s: chlayout:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, buf); \ + i, filter_ctx->inout##put_pads[i].name, buf); \ } \ } \ } \ @@ -106,12 +106,12 @@ int main(int argc, char **argv) /* create a link for each of the input pads */ for (i = 0; i < filter_ctx->input_count; i++) { AVFilterLink *link = av_mallocz(sizeof(AVFilterLink)); - link->type = filter_ctx->filter->inputs[i].type; + link->type = filter_ctx->input_pads[i].type; filter_ctx->inputs[i] = link; } for (i = 0; i < filter_ctx->output_count; i++) { AVFilterLink *link = av_mallocz(sizeof(AVFilterLink)); - link->type = filter_ctx->filter->outputs[i].type; + link->type = filter_ctx->output_pads[i].type; filter_ctx->outputs[i] = link; } diff --git a/libavfilter/graphdump.c b/libavfilter/graphdump.c index 45f64c0146..478afc654a 100644 --- a/libavfilter/graphdump.c +++ b/libavfilter/graphdump.c @@ -31,9 +31,10 @@ static int print_link_prop(AVBPrint *buf, AVFilterLink *link) { char *format; char layout[64]; + AVBPrint dummy_buffer = { 0 }; if (!buf) - buf = &(AVBPrint){ 0 }; /* dummy buffer */ + buf = &dummy_buffer; switch (link->type) { case AVMEDIA_TYPE_VIDEO: format = av_x_if_null(av_get_pix_fmt_name(link->format), "?"); diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index 0ce823a10d..453e962a7e 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -123,8 +123,8 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind return ret; } - if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") - && ctx->scale_sws_opts) { + 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/libmpcodecs/mp_image.c b/libavfilter/libmpcodecs/mp_image.c index 1ef5cbd55b..dbc1d62eb7 100644 --- a/libavfilter/libmpcodecs/mp_image.c +++ b/libavfilter/libmpcodecs/mp_image.c @@ -31,8 +31,13 @@ #include "libvo/fastmemcpy.h" //#include "libavutil/mem.h" +#include "libavutil/imgutils.h" void ff_mp_image_alloc_planes(mp_image_t *mpi) { + uint32_t temp[256]; + if (avpriv_set_systematic_pal2(temp, ff_mp2ff_pix_fmt(mpi->imgfmt)) >= 0) + mpi->flags |= MP_IMGFLAG_RGB_PALETTE; + // IF09 - allocate space for 4. plane delta info - unused if (mpi->imgfmt == IMGFMT_IF09) { mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+ @@ -65,8 +70,10 @@ void ff_mp_image_alloc_planes(mp_image_t *mpi) { } } else { mpi->stride[0]=mpi->width*mpi->bpp/8; - if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) + if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) { mpi->planes[1] = av_malloc(1024); + memcpy(mpi->planes[1], temp, 1024); + } } mpi->flags|=MP_IMGFLAG_ALLOCATED; } diff --git a/libavfilter/libmpcodecs/mp_image.h b/libavfilter/libmpcodecs/mp_image.h index d658ab03f1..c33703b77e 100644 --- a/libavfilter/libmpcodecs/mp_image.h +++ b/libavfilter/libmpcodecs/mp_image.h @@ -37,6 +37,8 @@ #define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t" #define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). +enum AVPixelFormat ff_mp2ff_pix_fmt(int mp); + //--------- codec's requirements (filled by the codec/vf) --------- //--- buffer content restrictions: diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c index bd45766641..ec9131ecab 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -91,13 +91,13 @@ static int movie_request_frame(AVFilterLink *outlink); static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec) { int i, ret, already = 0, stream_id = -1; - char type_char, dummy; + char type_char[2], dummy; AVStream *found = NULL; enum AVMediaType type; - ret = sscanf(spec, "d%[av]%d%c", &type_char, &stream_id, &dummy); + ret = sscanf(spec, "d%1[av]%d%c", type_char, &stream_id, &dummy); if (ret >= 1 && ret <= 2) { - type = type_char == 'v' ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO; + type = type_char[0] == 'v' ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO; ret = av_find_best_stream(avf, type, stream_id, -1, NULL, 0); if (ret < 0) { av_log(log, AV_LOG_ERROR, "No %s stream with index '%d' found\n", diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c index c03919c96d..4e79254ace 100644 --- a/libavfilter/vf_deshake.c +++ b/libavfilter/vf_deshake.c @@ -318,8 +318,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 53a60b1679..412786eaa6 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -48,7 +48,6 @@ #include "video.h" #include -#include #include FT_FREETYPE_H #include FT_GLYPH_H #if CONFIG_FONTCONFIG diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index d4305e7273..e2a4b3d4ee 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -202,7 +202,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf) } /* now wait for the next timestamp */ - if (buf->pts == AV_NOPTS_VALUE) { + if (buf->pts == AV_NOPTS_VALUE || av_fifo_size(s->fifo) <= 0) { return write_to_fifo(s->fifo, buf); } diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index ac23d4267f..6ca3624e16 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -129,6 +129,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) @@ -201,12 +202,13 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in) GradFunContext *gf = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *out; - int p, direct = 0; + int p, direct; if (in->perms & AV_PERM_WRITE) { direct = 1; out = in; } else { + direct = 0; out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); if (!out) { avfilter_unref_bufferp(&in); diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index b30f8ae8ad..ca683c9031 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -50,9 +50,10 @@ void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16 void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal); #define LUT_BITS (depth==16 ? 8 : 4) -#define LOAD(x) (((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth)) + (((1<<(16-depth))-1)>>1)) -#define STORE(x,val) (depth==8 ? dst[x] = (val) >> (16-depth)\ - : AV_WN16A(dst+(x)*2, (val) >> (16-depth))) +#define LOAD(x) (((depth == 8 ? src[x] : AV_RN16A(src + (x) * 2)) << (16 - depth))\ + + (((1 << (16 - depth)) - 1) >> 1)) +#define STORE(x,val) (depth == 8 ? dst[x] = (val) >> (16 - depth) : \ + AV_WN16A(dst + (x) * 2, (val) >> (16 - depth))) av_always_inline static uint32_t lowpass(int prev, int cur, int16_t *coef, int depth) @@ -154,6 +155,7 @@ static void denoise_depth(HQDN3DContext *hqdn3d, else denoise_temporal(src, dst, frame_ant, w, h, sstride, dstride, temporal, depth); + emms_c(); } #define denoise(...) \ @@ -327,12 +329,13 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in) AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *out; - int direct = 0, c; + int direct, c; if (in->perms & AV_PERM_WRITE) { direct = 1; out = in; } else { + direct = 0; out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); if (!out) { avfilter_unref_bufferp(&in); diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c index 382b8a71ed..12eb969b22 100644 --- a/libavfilter/vf_kerndeint.c +++ b/libavfilter/vf_kerndeint.c @@ -96,7 +96,7 @@ static int query_formats(AVFilterContext *ctx) static int config_props(AVFilterLink *inlink) { KerndeintContext *kerndeint = inlink->dst->priv; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format]; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); int ret; kerndeint->vsub = desc->log2_chroma_h; diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c index 6c87b3a8f0..70d1797435 100644 --- a/libavfilter/vf_mp.c +++ b/libavfilter/vf_mp.c @@ -217,6 +217,12 @@ zrmjpeg CpuCaps ff_gCpuCaps; //FIXME initialize this so optims work +enum AVPixelFormat ff_mp2ff_pix_fmt(int mp){ + int i; + for(i=0; conversion_map[i].fmt && mp != conversion_map[i].fmt; i++) + ; + return mp == conversion_map[i].fmt ? conversion_map[i].pix_fmt : AV_PIX_FMT_NONE; +} static void ff_sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam) { diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index dca4a8cd35..74eafcbd12 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -369,7 +369,7 @@ static int query_formats(AVFilterContext *ctx) static av_cold int init(AVFilterContext *ctx, const char *args) { YADIFContext *yadif = ctx->priv; - static const char *shorthand[] = { "mode", "parity", "enable", NULL }; + static const char *shorthand[] = { "mode", "parity", "deint", NULL }; int ret; yadif->csp = NULL; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 185d382f55..f5e37f8b72 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -248,7 +248,7 @@ static int color_config_props(AVFilterLink *inlink) if (av_image_check_size(test->w, test->h, 0, ctx) < 0) return AVERROR(EINVAL); - if (ret = config_props(inlink) < 0) + if ((ret = config_props(inlink)) < 0) return ret; av_log(ctx, AV_LOG_VERBOSE, "color:0x%02x%02x%02x%02x\n", diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 1e142f550f..ab02b0a530 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -57,7 +57,7 @@ #define GET_LIST_HEADER() \ fourcc_tag = avio_rl32(pb); \ - size = avio_rl32(pb); \ + size = avio_rl32(pb); \ if (fourcc_tag != LIST_TAG) \ return AVERROR_INVALIDDATA; \ fourcc_tag = avio_rl32(pb); @@ -72,8 +72,6 @@ typedef struct AudioTrack { } AudioTrack; typedef struct FourxmDemuxContext { - int width; - int height; int video_stream_index; int track_count; AudioTrack *tracks; @@ -91,6 +89,110 @@ static int fourxm_probe(AVProbeData *p) return AVPROBE_SCORE_MAX; } +static int parse_vtrk(AVFormatContext *s, + FourxmDemuxContext *fourxm, uint8_t *buf, int size, + int left) +{ + AVStream *st; + /* check that there is enough data */ + if (size != vtrk_SIZE || left < size + 8) { + return AVERROR_INVALIDDATA; + } + + /* allocate a new AVStream */ + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + avpriv_set_pts_info(st, 60, 1, fourxm->fps); + + fourxm->video_stream_index = st->index; + + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + st->codec->codec_id = AV_CODEC_ID_4XM; + st->codec->extradata_size = 4; + st->codec->extradata = av_malloc(4); + AV_WL32(st->codec->extradata, AV_RL32(buf + 16)); + st->codec->width = AV_RL32(buf + 36); + st->codec->height = AV_RL32(buf + 40); + + return 0; +} + + +static int parse_strk(AVFormatContext *s, + FourxmDemuxContext *fourxm, uint8_t *buf, int size, + int left) +{ + AVStream *st; + int track; + /* check that there is enough data */ + if (size != strk_SIZE || left < size + 8) + return AVERROR_INVALIDDATA; + + track = AV_RL32(buf + 8); + if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) { + av_log(s, AV_LOG_ERROR, "current_track too large\n"); + return AVERROR_INVALIDDATA; + } + if (track < 0) + return AVERROR_INVALIDDATA; + if (track + 1 > fourxm->track_count) { + fourxm->tracks = av_realloc_f(fourxm->tracks, track + 1, sizeof(AudioTrack)); + if (!fourxm->tracks) + return AVERROR(ENOMEM); + memset(&fourxm->tracks[fourxm->track_count], 0, + sizeof(AudioTrack) * (track + 1 - fourxm->track_count)); + fourxm->track_count = track + 1; + } + fourxm->tracks[track].adpcm = AV_RL32(buf + 12); + fourxm->tracks[track].channels = AV_RL32(buf + 36); + fourxm->tracks[track].sample_rate = AV_RL32(buf + 40); + fourxm->tracks[track].bits = AV_RL32(buf + 44); + fourxm->tracks[track].audio_pts = 0; + + if (fourxm->tracks[track].channels <= 0 || + fourxm->tracks[track].sample_rate <= 0 || + fourxm->tracks[track].bits <= 0) { + av_log(s, AV_LOG_ERROR, "audio header invalid\n"); + return AVERROR_INVALIDDATA; + } + if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) { + av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n"); + return AVERROR_INVALIDDATA; + } + + /* allocate a new AVStream */ + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->id = track; + avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate); + + fourxm->tracks[track].stream_index = st->index; + + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_tag = 0; + st->codec->channels = fourxm->tracks[track].channels; + st->codec->sample_rate = fourxm->tracks[track].sample_rate; + st->codec->bits_per_coded_sample = fourxm->tracks[track].bits; + st->codec->bit_rate = st->codec->channels * + st->codec->sample_rate * + st->codec->bits_per_coded_sample; + st->codec->block_align = st->codec->channels * + st->codec->bits_per_coded_sample; + + if (fourxm->tracks[track].adpcm){ + st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM; + } else if (st->codec->bits_per_coded_sample == 8) { + st->codec->codec_id = AV_CODEC_ID_PCM_U8; + } else + st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; + + return 0; +} + static int fourxm_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; @@ -100,11 +202,10 @@ static int fourxm_read_header(AVFormatContext *s) FourxmDemuxContext *fourxm = s->priv_data; unsigned char *header; int i, ret; - AVStream *st; fourxm->track_count = 0; - fourxm->tracks = NULL; - fourxm->fps = 1.0; + fourxm->tracks = NULL; + fourxm->fps = 1.0; /* skip the first 3 32-bit numbers */ avio_skip(pb, 12); @@ -119,7 +220,7 @@ static int fourxm_read_header(AVFormatContext *s) header = av_malloc(header_size); if (!header) return AVERROR(ENOMEM); - if (avio_read(pb, header, header_size) != header_size){ + if (avio_read(pb, header, header_size) != header_size) { av_free(header); return AVERROR(EIO); } @@ -127,123 +228,38 @@ static int fourxm_read_header(AVFormatContext *s) /* take the lazy approach and search for any and all vtrk and strk chunks */ for (i = 0; i < header_size - 8; i++) { fourcc_tag = AV_RL32(&header[i]); - size = AV_RL32(&header[i + 4]); + 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) { - if (header_size < i + 16) { + if (header_size - i < 16) { av_log(s, AV_LOG_ERROR, "std TAG truncated\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } fourxm->fps = av_int2float(AV_RL32(&header[i + 12])); } else if (fourcc_tag == vtrk_TAG) { - /* check that there is enough data */ - if (size != vtrk_SIZE) { - ret= AVERROR_INVALIDDATA; + if ((ret = parse_vtrk(s, fourxm, header + i, size, + header_size - i)) < 0) goto fail; - } - fourxm->width = AV_RL32(&header[i + 36]); - fourxm->height = AV_RL32(&header[i + 40]); - - /* allocate a new AVStream */ - st = avformat_new_stream(s, NULL); - if (!st){ - ret= AVERROR(ENOMEM); - goto fail; - } - avpriv_set_pts_info(st, 60, 1, fourxm->fps); - - fourxm->video_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_4XM; - st->codec->extradata_size = 4; - st->codec->extradata = av_malloc(4); - AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16])); - st->codec->width = fourxm->width; - st->codec->height = fourxm->height; i += 8 + size; } else if (fourcc_tag == strk_TAG) { - int current_track; - /* check that there is enough data */ - if (size != strk_SIZE) { - ret= AVERROR_INVALIDDATA; + if ((ret = parse_strk(s, fourxm, header + i, size, + header_size - i)) < 0) goto fail; - } - current_track = AV_RL32(&header[i + 8]); - if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){ - av_log(s, AV_LOG_ERROR, "current_track too large\n"); - ret = AVERROR_INVALIDDATA; - goto fail; - } - if (current_track + 1 > fourxm->track_count) { - fourxm->tracks = av_realloc_f(fourxm->tracks, - sizeof(AudioTrack), - current_track + 1); - if (!fourxm->tracks) { - ret = AVERROR(ENOMEM); - goto fail; - } - memset(&fourxm->tracks[fourxm->track_count], 0, - sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count)); - fourxm->track_count = current_track + 1; - } - fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]); - fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]); - fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]); - fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]); - fourxm->tracks[current_track].audio_pts = 0; - if( fourxm->tracks[current_track].channels <= 0 - || fourxm->tracks[current_track].sample_rate <= 0 - || fourxm->tracks[current_track].bits < 0){ - av_log(s, AV_LOG_ERROR, "audio header invalid\n"); - ret = AVERROR_INVALIDDATA; - 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 */ - st = avformat_new_stream(s, NULL); - if (!st){ - ret= AVERROR(ENOMEM); - goto fail; - } - - st->id = current_track; - avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate); - - fourxm->tracks[current_track].stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; - st->codec->channels = fourxm->tracks[current_track].channels; - st->codec->sample_rate = fourxm->tracks[current_track].sample_rate; - st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - if (fourxm->tracks[current_track].adpcm){ - st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM; - }else if (st->codec->bits_per_coded_sample == 8){ - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - }else - st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; } } /* skip over the LIST-MOVI chunk (which is where the stream should be */ GET_LIST_HEADER(); - if (fourcc_tag != MOVI_TAG){ - ret= AVERROR_INVALIDDATA; + if (fourcc_tag != MOVI_TAG) { + ret = AVERROR_INVALIDDATA; goto fail; } @@ -262,7 +278,7 @@ static int fourxm_read_packet(AVFormatContext *s, AVPacket *pkt) { FourxmDemuxContext *fourxm = s->priv_data; - AVIOContext *pb = s->pb; + AVIOContext *pb = s->pb; unsigned int fourcc_tag; unsigned int size; int ret = 0; @@ -272,18 +288,16 @@ static int fourxm_read_packet(AVFormatContext *s, int audio_frame_count; while (!packet_read) { - if ((ret = avio_read(s->pb, header, 8)) < 0) return ret; fourcc_tag = AV_RL32(&header[0]); - size = AV_RL32(&header[4]); + size = AV_RL32(&header[4]); if (url_feof(pb)) return AVERROR(EIO); switch (fourcc_tag) { - case LIST_TAG: /* this is a good time to bump the video pts */ - fourxm->video_pts ++; + fourxm->video_pts++; /* skip the LIST-* tag and move on to the next fourcc */ avio_rl32(pb); @@ -300,45 +314,43 @@ static int fourxm_read_packet(AVFormatContext *s, if (size + 8 < size || av_new_packet(pkt, size + 8)) return AVERROR(EIO); pkt->stream_index = fourxm->video_stream_index; - pkt->pts = fourxm->video_pts; - pkt->pos = avio_tell(s->pb); + pkt->pts = fourxm->video_pts; + pkt->pos = avio_tell(s->pb); memcpy(pkt->data, header, 8); ret = avio_read(s->pb, &pkt->data[8], size); - if (ret < 0){ + if (ret < 0) { av_free_packet(pkt); - }else + } else packet_read = 1; break; case snd__TAG: track_number = avio_rl32(pb); avio_skip(pb, 4); - size-=8; + size -= 8; - if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) { - ret= av_get_packet(s->pb, pkt, size); - if(ret<0) + if (track_number < fourxm->track_count && + fourxm->tracks[track_number].channels > 0) { + ret = av_get_packet(s->pb, pkt, size); + if (ret < 0) return AVERROR(EIO); pkt->stream_index = fourxm->tracks[track_number].stream_index; - pkt->pts = fourxm->tracks[track_number].audio_pts; + pkt->pts = fourxm->tracks[track_number].audio_pts; packet_read = 1; /* pts accounting */ audio_frame_count = size; if (fourxm->tracks[track_number].adpcm) - audio_frame_count -= - 2 * (fourxm->tracks[track_number].channels); - audio_frame_count /= - fourxm->tracks[track_number].channels; - if (fourxm->tracks[track_number].adpcm){ + audio_frame_count -= 2 * (fourxm->tracks[track_number].channels); + audio_frame_count /= fourxm->tracks[track_number].channels; + if (fourxm->tracks[track_number].adpcm) { audio_frame_count *= 2; - }else + } else audio_frame_count /= - (fourxm->tracks[track_number].bits / 8); + (fourxm->tracks[track_number].bits / 8); fourxm->tracks[track_number].audio_pts += audio_frame_count; - } else { avio_skip(pb, size); } diff --git a/libavformat/Makefile b/libavformat/Makefile index 756059795e..85799d47c5 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -13,7 +13,6 @@ OBJS = allformats.o \ cutils.o \ id3v1.o \ id3v2.o \ - log2_tab.o \ metadata.o \ mux.o \ options.o \ @@ -45,6 +44,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ rtpdec_vp8.o \ rtpdec_xiph.o OBJS-$(CONFIG_RTPENC_CHAIN) += rtpenc_chain.o rtp.o +OBJS-$(CONFIG_SHARED) += log2_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index 49e19307d5..2cde39da7b 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 8d466fa815..4a2629888b 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -192,7 +192,7 @@ static int aiff_probe(AVProbeData *p) static int aiff_read_header(AVFormatContext *s) { int ret, size, filesize; - int64_t offset = 0; + int64_t offset = 0, position; uint32_t tag; unsigned version = AIFF_C_VERSION1; AVIOContext *pb = s->pb; @@ -236,6 +236,7 @@ static int aiff_read_header(AVFormatContext *s) goto got_sound; break; case MKTAG('I', 'D', '3', ' '): + position = avio_tell(pb); ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); if (id3v2_extra_meta) if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { @@ -243,6 +244,8 @@ static int aiff_read_header(AVFormatContext *s) return ret; } ff_id3v2_free_extra_meta(&id3v2_extra_meta); + if (position + size > avio_tell(pb)) + avio_skip(pb, position + size - avio_tell(pb)); break; case MKTAG('F', 'V', 'E', 'R'): /* Version chunk */ version = avio_rb32(pb); diff --git a/libavformat/ape.c b/libavformat/ape.c index 551513d3d1..2cd3d80f34 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -253,7 +253,7 @@ static int ape_read_header(AVFormatContext * s) ape->totalframes); return AVERROR_INVALIDDATA; } - 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); @@ -274,7 +274,9 @@ static int ape_read_header(AVFormatContext * s) 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"); diff --git a/libavformat/apetag.c b/libavformat/apetag.c index a445c84aef..0d9b067d23 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; + } if (flags & APE_TAG_FLAG_IS_BINARY) { uint8_t filename[1024]; enum AVCodecID id; @@ -114,7 +116,7 @@ static int ape_tag_read_field(AVFormatContext *s) int64_t 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]; int64_t tag_start; diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 2dcdf56adb..1f799bc234 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -718,7 +718,9 @@ static int asf_read_header(AVFormatContext *s) 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)) { diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 7436b63cfb..688ce001ae 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -490,7 +490,8 @@ static int avi_read_header(AVFormatContext *s) avi->dv_demux = avpriv_dv_init_demux(s); if (!avi->dv_demux) goto fail; - } + } else + goto fail; s->streams[0]->priv_data = ast; avio_skip(pb, 3 * 4); ast->scale = avio_rl32(pb); @@ -636,6 +637,8 @@ static int avi_read_header(AVFormatContext *s) st->codec->codec_tag = tag1; st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts. + if (st->codec->codec_tag == MKTAG('V', 'S', 'S', 'H')) + st->need_parsing = AVSTREAM_PARSE_FULL; if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){ st->codec->extradata_size+= 9; @@ -703,7 +706,9 @@ static int avi_read_header(AVFormatContext *s) } 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); @@ -790,7 +795,12 @@ static int avi_read_header(AVFormatContext *s) 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); + avi->non_interleaved |= (s->flags & AVFMT_FLAG_SORT_DTS); + + if ((ret = guess_ni_flag(s)) < 0) + return ret; + + avi->non_interleaved |= ret; for(i=0; inb_streams; i++){ AVStream *st = s->streams[i]; if(st->nb_index_entries) @@ -816,8 +826,10 @@ static int avi_read_header(AVFormatContext *s) return 0; } -static int read_gab2_sub(AVStream *st, AVPacket *pkt) { - if (pkt->data && !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; @@ -951,7 +963,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; @@ -993,14 +1005,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) { @@ -1058,6 +1073,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){ @@ -1296,7 +1313,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; } @@ -1327,6 +1344,64 @@ 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_mallocz_array(s->nb_streams, sizeof(*idx)); + if (!idx) + return AVERROR(ENOMEM); + + 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; @@ -1357,32 +1432,10 @@ static int guess_ni_flag(AVFormatContext *s){ first_end= st->index_entries[n-1].pos; } avio_seek(s->pb, oldpos, SEEK_SET); + if (last_start > first_end) return 1; - idx= av_mallocz(sizeof(*idx) * s->nb_streams); - for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) { - int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2; - min_pos = INT64_MAX; - - for (i=0; inb_streams; i++) { - AVStream *st = s->streams[i]; - int n= st->nb_index_entries; - while (idx[i]index_entries[idx[i]].pos < pos) - idx[i]++; - if (idx[i] < n) { - min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q)); - min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos); - } - if (idx[i]) - max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q)); - } - if(max_dts - min_dts > 2*AV_TIME_BASE) { - av_free(idx); - return 1; - } - } - av_free(idx); - return 0; + return check_stream_max_drift(s); } static int avi_load_index(AVFormatContext *s) @@ -1449,6 +1502,12 @@ 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); @@ -1479,8 +1538,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. */ - av_assert0(stream_index == 0); - if(avio_seek(s->pb, pos, SEEK_SET) < 0) return -1; diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 15f07943f6..918992f5a9 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -523,7 +523,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) int size= pkt->size; av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index); - while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB){ + while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count){ AVPacket empty_packet; if(pkt->dts - avist->packet_count > 60000){ diff --git a/libavformat/avio.c b/libavformat/avio.c index 6d8a8bb92a..36411990fc 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -210,7 +210,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))); @@ -278,7 +280,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int av_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 7a73a1791f..dc7dbb233b 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -216,6 +216,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } + if (offset < 0) + return AVERROR(EINVAL); + offset1 = offset - pos; if (!s->must_flush && (!s->direct || !s->seek) && offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { diff --git a/libavformat/bfi.c b/libavformat/bfi.c index a28e09a4f1..212a6119da 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -134,6 +134,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); @@ -142,9 +146,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); @@ -156,6 +158,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 9f6ea4a415..9930856f33 100644 --- a/libavformat/bit.c +++ b/libavformat/bit.c @@ -119,8 +119,12 @@ static int write_header(AVFormatContext *s) { AVCodecContext *enc = s->streams[0]->codec; - enc->codec_id = AV_CODEC_ID_G729; - enc->channels = 1; + if ((enc->codec_id != AV_CODEC_ID_G729) || enc->channels != 1) { + av_log(s, AV_LOG_ERROR, + "only codec g729 with 1 channel is supported by this format\n"); + return AVERROR(EINVAL); + } + enc->bits_per_coded_sample = 16; enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3; @@ -133,6 +137,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) GetBitContext gb; int i; + if (pkt->size != 10) + return AVERROR(EINVAL); + avio_wl16(pb, SYNC_WORD); avio_wl16(pb, 8 * 10); diff --git a/libavformat/cdxl.c b/libavformat/cdxl.c index 185b745bb0..226a704650 100644 --- a/libavformat/cdxl.c +++ b/libavformat/cdxl.c @@ -127,6 +127,8 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) height = AV_RB16(&cdxl->header[16]); palette_size = AV_RB16(&cdxl->header[20]); audio_size = AV_RB16(&cdxl->header[22]); + if (FFALIGN(width, 16) * (uint64_t)height * cdxl->header[19] > INT_MAX) + return AVERROR_INVALIDDATA; image_size = FFALIGN(width, 16) * height * cdxl->header[19] / 8; video_size = palette_size + image_size; diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c index b8ca57c0a4..4a54680056 100644 --- a/libavformat/dsicin.c +++ b/libavformat/dsicin.c @@ -155,6 +155,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/dtsdec.c b/libavformat/dtsdec.c index 5c05758327..009dd5c456 100644 --- a/libavformat/dtsdec.c +++ b/libavformat/dtsdec.c @@ -34,6 +34,7 @@ static int dts_probe(AVProbeData *p) uint32_t state = -1; int markers[3] = {0}; int sum, max; + int64_t diff = 0; buf = p->buf; @@ -54,12 +55,16 @@ static int dts_probe(AVProbeData *p) if (state == DCA_MARKER_14B_LE) if ((bytestream_get_be16(&bufp) & 0xF0FF) == 0xF007) markers[2]++; + + if (buf - p->buf >= 4) + diff += FFABS(AV_RL16(buf) - AV_RL16(buf-4)); } sum = markers[0] + markers[1] + markers[2]; max = markers[1] > markers[0]; max = markers[2] > markers[max] ? 2 : max; if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 && - markers[max] * 4 > sum * 3) + markers[max] * 4 > sum * 3 && + diff / p->buf_size > 200) return AVPROBE_SCORE_MAX/2+1; return 0; diff --git a/libavformat/dv.c b/libavformat/dv.c index a04735ac25..cf513a83b2 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -113,7 +113,7 @@ static const int dv_audio_frequency[3] = { * 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; @@ -358,7 +358,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/dvenc.c b/libavformat/dvenc.c index 0841d0e636..0b3811e838 100644 --- a/libavformat/dvenc.c +++ b/libavformat/dvenc.c @@ -376,8 +376,8 @@ static int dv_write_header(AVFormatContext *s) break; } } - if (tcr) - return av_timecode_init_from_string(&dvc->tc, rate, tcr->value, s); + if (tcr && av_timecode_init_from_string(&dvc->tc, rate, tcr->value, s) >= 0) + return 0; return av_timecode_init(&dvc->tc, rate, 0, 0, s); } diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 5b821a9cf5..4484355e94 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -453,8 +453,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; } @@ -545,12 +546,16 @@ static int ea_read_packet(AVFormatContext *s, case AV_CODEC_ID_ADPCM_EA_R1: case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_IMA_EA_EACS: - if (pkt->size >= 4) - pkt->duration = AV_RL32(pkt->data); - break; case AV_CODEC_ID_ADPCM_EA_R3: - if (pkt->size >= 4) + if (pkt->size < 4) { + av_log(s, AV_LOG_ERROR, "Packet is too short\n"); + av_free_packet(pkt); + return AVERROR_INVALIDDATA; + } + if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3) pkt->duration = AV_RB32(pkt->data); + else + pkt->duration = AV_RL32(pkt->data); break; case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: pkt->duration = ret * 2 / ea->num_channels; diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c index 02cf790f87..2b1891fa23 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -77,6 +77,7 @@ static int ffm_read_data(AVFormatContext *s, FFMContext *ffm = s->priv_data; AVIOContext *pb = s->pb; int len, fill_size, size1, frame_offset, id; + int64_t last_pos = -1; size1 = size; while (size > 0) { @@ -96,9 +97,11 @@ static int ffm_read_data(AVFormatContext *s, avio_seek(pb, tell, SEEK_SET); } id = avio_rb16(pb); /* PACKET_ID */ - if (id != PACKET_ID) + if (id != PACKET_ID) { if (ffm_resync(s, id) < 0) return -1; + last_pos = avio_tell(pb); + } fill_size = avio_rb16(pb); ffm->dts = avio_rb64(pb); frame_offset = avio_rb16(pb); @@ -112,7 +115,9 @@ static int ffm_read_data(AVFormatContext *s, if (!frame_offset) { /* This packet has no frame headers in it */ if (avio_tell(pb) >= ffm->packet_size * 3LL) { - avio_seek(pb, -ffm->packet_size * 2LL, SEEK_CUR); + int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos); + seekback = FFMAX(seekback, 0); + avio_seek(pb, -seekback, SEEK_CUR); goto retry_read; } /* This is bad, we cannot find a valid frame header */ @@ -292,6 +297,11 @@ static int ffm2_read_header(AVFormatContext *s) case MKBETAG('S', 'T', 'V', 'I'): codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); + if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { + av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", + codec->time_base.num, codec->time_base.den); + goto fail; + } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); @@ -347,7 +357,7 @@ static int ffm2_read_header(AVFormatContext *s) } /* get until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) + while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ @@ -416,6 +426,11 @@ static int ffm_read_header(AVFormatContext *s) case AVMEDIA_TYPE_VIDEO: codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); + if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { + av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", + codec->time_base.num, codec->time_base.den); + goto fail; + } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); @@ -477,7 +492,7 @@ static int ffm_read_header(AVFormatContext *s) } /* get until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) + while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index ecc47e6ccd..6b19cd5923 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -277,11 +277,9 @@ fail: static int flac_probe(AVProbeData *p) { - const uint8_t *bufptr = p->buf; - const 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/flvdec.c b/libavformat/flvdec.c index 09a77c4852..9329b483a4 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -199,7 +199,7 @@ static int flv_same_video_codec(AVCodecContext *vcodec, int flags) } } -static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { +static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid, int read) { AVCodecContext *vcodec = vstream->codec; switch(flv_codecid) { case FLV_CODECID_H263 : vcodec->codec_id = AV_CODEC_ID_FLV1 ; break; @@ -210,11 +210,17 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_co case FLV_CODECID_VP6A : if(flv_codecid == FLV_CODECID_VP6A) vcodec->codec_id = AV_CODEC_ID_VP6A; - if(vcodec->extradata_size != 1) { - vcodec->extradata_size = 1; - vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE); + if (read) { + if (vcodec->extradata_size != 1) { + vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE); + if (vcodec->extradata) + vcodec->extradata_size = 1; + } + if (vcodec->extradata) + vcodec->extradata[0] = avio_r8(s->pb); + else + avio_skip(s->pb, 1); } - vcodec->extradata[0] = avio_r8(s->pb); return 1; // 1 byte body size adjustment for flv_read_packet() case FLV_CODECID_H264: vcodec->codec_id = AV_CODEC_ID_H264; @@ -392,7 +398,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst acodec = astream ? astream->codec : NULL; vcodec = vstream ? vstream->codec : NULL; - if (amf_type == AMF_DATA_TYPE_NUMBER) { + if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) { if (!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE; else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0)) @@ -406,13 +412,21 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst st->codec->codec_id = AV_CODEC_ID_TEXT; } else if (flv->trust_metadata) { if (!strcmp(key, "videocodecid") && vcodec) { - flv_set_video_codec(s, vstream, num_val); + flv_set_video_codec(s, vstream, num_val, 0); } else if (!strcmp(key, "audiocodecid") && acodec) { - flv_set_audio_codec(s, astream, acodec, num_val); + int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET; + flv_set_audio_codec(s, astream, acodec, id); } else if (!strcmp(key, "audiosamplerate") && acodec) { acodec->sample_rate = num_val; + } else if (!strcmp(key, "audiosamplesize") && acodec) { + acodec->bits_per_coded_sample = num_val; + } else if (!strcmp(key, "stereo") && acodec) { + acodec->channels = num_val + 1; + acodec->channel_layout = acodec->channels == 2 ? + AV_CH_LAYOUT_STEREO : + AV_CH_LAYOUT_MONO; } else if (!strcmp(key, "width") && vcodec) { vcodec->width = num_val; @@ -713,13 +727,13 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[i]; if (stream_type == FLV_STREAM_TYPE_AUDIO) { if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - flv_same_audio_codec(st->codec, flags)) { + (s->audio_codec_id || flv_same_audio_codec(st->codec, flags))) { break; } } else if (stream_type == FLV_STREAM_TYPE_VIDEO) { if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - flv_same_video_codec(st->codec, flags)) { + (s->video_codec_id || flv_same_video_codec(st->codec, flags))) { break; } } else if (stream_type == FLV_STREAM_TYPE_DATA) { @@ -795,7 +809,7 @@ retry_duration: sample_rate = ctx.sample_rate; } } else if(stream_type == FLV_STREAM_TYPE_VIDEO) { - size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); + size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1); } if (st->codec->codec_id == AV_CODEC_ID_AAC || diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 502da0f0c5..893536513c 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -218,6 +218,18 @@ static int flv_write_header(AVFormatContext *s) avcodec_get_name(enc->codec_id), i); return AVERROR(EINVAL); } + if (enc->codec_id == AV_CODEC_ID_MPEG4 || + enc->codec_id == AV_CODEC_ID_H263) { + int error = enc->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL; + av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING, + "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id)); + + if (error) { + av_log(s, AV_LOG_ERROR, + "use vstrict=-1 / -strict -1 to use it anyway.\n"); + return AVERROR(EINVAL); + } + } break; case AVMEDIA_TYPE_AUDIO: audio_enc = enc; @@ -463,7 +475,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) avio_w8(pb, FLV_TAG_TYPE_VIDEO); flags = enc->codec_tag; - if (flags == 0) { + if (flags <= 0 || flags > 15) { av_log(s, AV_LOG_ERROR, "Video codec '%s' is not compatible with FLV\n", avcodec_get_name(enc->codec_id)); @@ -493,10 +505,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } else if (enc->codec_id == AV_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, "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) diff --git a/libavformat/gxf.c b/libavformat/gxf.c index 86e629135d..464a9bd747 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -548,7 +548,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 667fdbdcbb..30fd454c49 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/hls.c b/libavformat/hls.c index f515dfb7f1..4a67c2db69 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -560,12 +560,14 @@ static int hls_read_header(AVFormatContext *s) /* Create new AVStreams for each stream in this variant */ for (j = 0; j < v->ctx->nb_streams; j++) { AVStream *st = avformat_new_stream(s, NULL); + AVStream *ist = v->ctx->streams[j]; if (!st) { ret = AVERROR(ENOMEM); goto fail; } ff_program_add_stream_index(s, i, stream_offset + j); st->id = i; + avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); avcodec_copy_context(st->codec, v->ctx->streams[j]->codec); if (v->bandwidth) av_dict_set(&st->metadata, "variant_bitrate", bitrate_str, diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9eed9577b8..164a079877 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -252,18 +252,20 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) AVFormatContext *oc = hls->avf; AVStream *st = s->streams[pkt->stream_index]; int64_t end_pts = hls->recording_time * hls->number; - int ret; + int ret, can_split = 1; if (hls->start_pts == AV_NOPTS_VALUE) { hls->start_pts = pkt->pts; hls->end_pts = pkt->pts; } - if ((hls->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && - av_compare_ts(pkt->pts - hls->start_pts, st->time_base, - end_pts, AV_TIME_BASE_Q) >= 0 && - pkt->flags & AV_PKT_FLAG_KEY) { + if (hls->has_video) { + can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && + pkt->flags & AV_PKT_FLAG_KEY; + } + if (can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base, + end_pts, AV_TIME_BASE_Q) >= 0) { ret = append_entry(hls, av_rescale(pkt->pts - hls->end_pts, st->time_base.num, st->time_base.den)); diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index f805f5bac2..65c521dbe3 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -490,9 +490,10 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag } apic->len = taglen; - apic->data = av_malloc(taglen); + apic->data = av_malloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE); if (!apic->data || !apic->len || avio_read(pb, apic->data, taglen) != taglen) goto fail; + memset(apic->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE); new_extra->tag = "APIC"; new_extra->data = apic; @@ -704,9 +705,11 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t uint8_t *b; b = buffer; - while (avio_tell(s->pb) < end && b - buffer < tlen) { + while (avio_tell(s->pb) < end && b - buffer < tlen && !s->pb->eof_reached) { *b++ = avio_r8(s->pb); - if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && b - buffer < tlen) { + if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && + b - buffer < tlen && + !s->pb->eof_reached ) { uint8_t val = avio_r8(s->pb); *b++ = val ? val : avio_r8(s->pb); } diff --git a/libavformat/idcin.c b/libavformat/idcin.c index bede04075e..fdd19e14a5 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 6f843d7bc9..8cdd72e33a 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; @@ -194,6 +196,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 0e945da7a3..02ba33c181 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -249,6 +249,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) @@ -409,6 +414,7 @@ static int iff_read_header(AVFormatContext *s) if (!st->codec->extradata) return AVERROR(ENOMEM); } + av_assert0(st->codec->extradata_size >= IFF_EXTRA_VIDEO_SIZE); buf = st->codec->extradata; bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE); bytestream_put_byte(&buf, iff->bitmap_compression); diff --git a/libavformat/isom.c b/libavformat/isom.c index 3b609db00a..93db737419 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -279,6 +279,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = { { AV_CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, { AV_CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, { AV_CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, + { AV_CODEC_ID_PCM_S16BE, MKTAG('l', 'p', 'c', 'm') }, { AV_CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') }, { AV_CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') }, { AV_CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') }, diff --git a/libavformat/isom.h b/libavformat/isom.h index 0360c53f11..83fb91851c 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -161,6 +161,7 @@ typedef struct MOVContext { int use_absolute_path; int ignore_editlist; int64_t next_root_atom; ///< offset of the next root atom + int atom_depth; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c index 233eab8382..9dfb4e4fab 100644 --- a/libavformat/latmenc.c +++ b/libavformat/latmenc.c @@ -156,6 +156,15 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n"); return AVERROR_INVALIDDATA; } + + if (!s->streams[0]->codec->extradata) { + if(pkt->size > 2 && pkt->data[0] == 0x56 && (pkt->data[1] >> 4) == 0xe && + (AV_RB16(pkt->data + 1) & 0x1FFF) + 3 == pkt->size) + return ff_raw_write_packet(s, pkt); + else + return AVERROR_INVALIDDATA; + } + if (pkt->size > 0x1fff) goto too_large; diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c index aa8edccb59..4ba9392aa0 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 2a06fe12a7..d3a8dbd6cd 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/lxfdec.c b/libavformat/lxfdec.c index 90c49749a6..99257397f9 100644 --- a/libavformat/lxfdec.c +++ b/libavformat/lxfdec.c @@ -258,6 +258,7 @@ static int lxf_read_header(AVFormatContext *s) st->codec->bit_rate = 1000000 * ((video_params >> 14) & 0xFF); st->codec->codec_tag = video_params & 0xF; st->codec->codec_id = ff_codec_get_id(lxf_tags, st->codec->codec_tag); + st->need_parsing = AVSTREAM_PARSE_HEADERS; av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n", record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF, diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c index e72fb42f1d..2deff32906 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 64d0a459b4..82a135c92c 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" , AV_CODEC_ID_AAC}, {"A_AC3" , AV_CODEC_ID_AC3}, @@ -32,7 +35,7 @@ const CodecTags ff_mkv_codec_tags[]={ {"A_MPEG/L2" , AV_CODEC_ID_MP2}, {"A_MPEG/L1" , AV_CODEC_ID_MP2}, {"A_MPEG/L3" , AV_CODEC_ID_MP3}, - {"A_OPUS", AV_CODEC_ID_OPUS}, + {"A_OPUS" , AV_CODEC_ID_OPUS}, {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F32LE}, {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F64LE}, {"A_PCM/INT/BIG" , AV_CODEC_ID_PCM_S16BE}, @@ -111,7 +114,7 @@ const char * const ff_matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUN "bottom_top", "top_bottom", "checkerboard_rl", - "checkerboard_lr" + "checkerboard_lr", "row_interleaved_rl", "row_interleaved_lr", "col_interleaved_rl", diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 4da4f1851f..459dc1e710 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1231,7 +1231,8 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, int i; for (i=0; i < list->nb_elem; i++) { - const char *lang= (tags[i].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"); @@ -1345,13 +1346,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; @@ -1672,8 +1677,10 @@ static int matroska_read_header(AVFormatContext *s) avio_wl16(&b, 1); avio_wl16(&b, track->audio.channels); avio_wl16(&b, track->audio.bitdepth); + if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX) + return AVERROR_INVALIDDATA; avio_wl32(&b, track->audio.out_samplerate); - avio_wl32(&b, matroska->ctx->duration * track->audio.out_samplerate); + avio_wl32(&b, av_rescale((matroska->duration * matroska->time_scale), track->audio.out_samplerate, AV_TIME_BASE * 1000)); } else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 || codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) { extradata_offset = 26; @@ -1694,6 +1701,10 @@ static int matroska_read_header(AVFormatContext *s) track->audio.sub_packet_h = avio_rb16(&b); track->audio.frame_size = avio_rb16(&b); track->audio.sub_packet_size = avio_rb16(&b); + if (flavor <= 0 || track->audio.coded_framesize <= 0 || + 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 == AV_CODEC_ID_RA_288) { st->codec->block_align = track->audio.coded_framesize; @@ -1762,7 +1773,8 @@ static int matroska_read_header(AVFormatContext *s) av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, 1000000000, track->default_duration, 30000); #if FF_API_R_FRAME_RATE - st->r_frame_rate = st->avg_frame_rate; + if (st->avg_frame_rate.num < st->avg_frame_rate.den * 1000L) + st->r_frame_rate = st->avg_frame_rate; #endif } @@ -1881,6 +1893,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++) { @@ -1893,10 +1906,10 @@ static void matroska_clear_queue(MatroskaDemuxContext *matroska) } static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, - int size, int type, + int* buf_size, int type, uint32_t **lace_buf, int *laces) { - int res = 0, n; + int res = 0, n, size = *buf_size; uint8_t *data = *buf; uint32_t *lace_size; @@ -1957,7 +1970,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, case 0x3: /* EBML lacing */ { uint64_t num; - uint32_t total; + uint64_t total; n = matroska_ebmlnum_uint(matroska, data, size, &num); if (n < 0) { av_log(matroska->ctx, AV_LOG_INFO, @@ -1994,6 +2007,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, *buf = data; *lace_buf = lace_size; + *buf_size = size; return res; } @@ -2168,6 +2182,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, uint32_t *lace_size = NULL; int n, flags, laces = 0; uint64_t num; + int trust_default_duration = 1; if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) { av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n"); @@ -2216,13 +2231,21 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, matroska->skip_to_keyframe = 0; } - res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1, + res = matroska_parse_laces(matroska, &data, &size, (flags & 0x06) >> 1, &lace_size, &laces); if (res) goto end; - if (!block_duration) + if (track->audio.samplerate == 8000) { + // If this is needed for more codecs, then add them here + if (st->codec->codec_id == AV_CODEC_ID_AC3) { + if(track->audio.samplerate != st->codec->sample_rate || !st->codec->frame_size) + trust_default_duration = 0; + } + } + + if (!block_duration && trust_default_duration) block_duration = track->default_duration * laces / matroska->time_scale; if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time)) @@ -2243,7 +2266,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, st->codec->codec_id == AV_CODEC_ID_ATRAC3) && st->codec->block_align && track->audio.sub_packet_size) { - res = matroska_parse_rm_audio(matroska, track, st, data, size, + res = matroska_parse_rm_audio(matroska, track, st, data, + lace_size[n], timecode, pos); if (res) goto end; @@ -2318,7 +2342,6 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska) } } - if (res < 0) matroska->done = 1; return res; } @@ -2370,7 +2393,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; @@ -2388,7 +2411,6 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, avio_seek(s->pb, st->index_entries[st->nb_index_entries-1].pos, SEEK_SET); matroska->current_id = 0; while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { - matroska->prev_pkt = NULL; matroska_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0) break; @@ -2400,6 +2422,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, goto err; index_min = index; + tracks = matroska->tracks.elem; for (i=0; i < matroska->tracks.nb_elem; i++) { tracks[i].audio.pkt_cnt = 0; tracks[i].audio.sub_packet_cnt = 0; @@ -2408,10 +2431,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 1840f90b22..a8b829c3b3 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -95,6 +95,8 @@ typedef struct MatroskaMuxContext { AVPacket cur_audio_pkt; int have_attachments; + + int64_t ts_offset; } MatroskaMuxContext; @@ -790,13 +792,26 @@ 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); return 0; } +static int mkv_check_tag(AVDictionary *m) +{ + AVDictionaryEntry *t = NULL; + + while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) + if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode")) + return 1; + + return 0; +} + static int mkv_write_tags(AVFormatContext *s) { ebml_master tags = {0}; @@ -804,7 +819,7 @@ static int mkv_write_tags(AVFormatContext *s) ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL); - if (av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) { + if (mkv_check_tag(s->metadata)) { ret = mkv_write_tag(s, s->metadata, 0, 0, &tags); if (ret < 0) return ret; } @@ -812,7 +827,7 @@ static int mkv_write_tags(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - if (!av_dict_get(st->metadata, "", 0, AV_DICT_IGNORE_SUFFIX)) + if (!mkv_check_tag(st->metadata)) continue; ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags); @@ -822,7 +837,7 @@ static int mkv_write_tags(AVFormatContext *s) for (i = 0; i < s->nb_chapters; i++) { AVChapter *ch = s->chapters[i]; - if (!av_dict_get(ch->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) + if (!mkv_check_tag(ch->metadata)) continue; ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags); @@ -970,7 +985,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); } @@ -1249,9 +1267,18 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) AVIOContext *pb = s->pb->seekable ? s->pb : mkv->dyn_bc; AVCodecContext *codec = s->streams[pkt->stream_index]->codec; int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY); - int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; + int64_t ts; int cluster_size = avio_tell(pb) - (s->pb->seekable ? mkv->cluster_pos : 0); + if (pkt->dts < 0 && !mkv->ts_offset) + mkv->ts_offset = -pkt->dts; + + pkt->dts += mkv->ts_offset; + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts += mkv->ts_offset; + + ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; + // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or // after 4k and on a keyframe if (mkv->cluster_pos != -1 && @@ -1353,6 +1380,32 @@ static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance) return 0; } +const AVCodecTag additional_audio_tags[] = { + { AV_CODEC_ID_ALAC, 0XFFFFFFFF }, + { AV_CODEC_ID_EAC3, 0XFFFFFFFF }, + { AV_CODEC_ID_MLP, 0xFFFFFFFF }, + { AV_CODEC_ID_OPUS, 0xFFFFFFFF }, + { AV_CODEC_ID_PCM_S16BE, 0xFFFFFFFF }, + { AV_CODEC_ID_PCM_S24BE, 0xFFFFFFFF }, + { AV_CODEC_ID_PCM_S32BE, 0xFFFFFFFF }, + { AV_CODEC_ID_QDM2, 0xFFFFFFFF }, + { AV_CODEC_ID_RA_144, 0xFFFFFFFF }, + { AV_CODEC_ID_RA_288, 0xFFFFFFFF }, + { AV_CODEC_ID_COOK, 0xFFFFFFFF }, + { AV_CODEC_ID_TRUEHD, 0xFFFFFFFF }, + { AV_CODEC_ID_TTA, 0xFFFFFFFF }, + { AV_CODEC_ID_WAVPACK, 0xFFFFFFFF }, + { AV_CODEC_ID_NONE, 0xFFFFFFFF } +}; + +const AVCodecTag additional_video_tags[] = { + { AV_CODEC_ID_RV10, 0xFFFFFFFF }, + { AV_CODEC_ID_RV20, 0xFFFFFFFF }, + { AV_CODEC_ID_RV30, 0xFFFFFFFF }, + { AV_CODEC_ID_RV40, 0xFFFFFFFF }, + { AV_CODEC_ID_NONE, 0xFFFFFFFF } +}; + #if CONFIG_MATROSKA_MUXER AVOutputFormat ff_matroska_muxer = { .name = "matroska", @@ -1369,6 +1422,10 @@ AVOutputFormat ff_matroska_muxer = { .write_trailer = mkv_write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT, + .codec_tag = (const AVCodecTag* const []){ + ff_codec_bmp_tags, ff_codec_wav_tags, + additional_audio_tags, additional_video_tags, 0 + }, .subtitle_codec = AV_CODEC_ID_SSA, .query_codec = mkv_query_codec, }; @@ -1405,5 +1462,8 @@ AVOutputFormat ff_matroska_audio_muxer = { .write_packet = mkv_write_packet, .write_trailer = mkv_write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT, + .codec_tag = (const AVCodecTag* const []){ + ff_codec_wav_tags, additional_audio_tags, 0 + }, }; #endif diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index 86a0575e59..d5d2f0c171 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -309,14 +309,16 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim return 0; fail: av_freep(&stream_selection); - mmsh_close(h); av_dlog(NULL, "Connection failed with error %d\n", err); return err; } static int mmsh_open(URLContext *h, const char *uri, int flags) { - return mmsh_open_internal(h, uri, flags, 0, 0); + int ret = mmsh_open_internal(h, uri, flags, 0, 0); + if (ret < 0) + mmsh_close(h); + return ret; } static int handle_chunk_type(MMSHContext *mmsh) diff --git a/libavformat/mov.c b/libavformat/mov.c index 6c78adbd2a..9f226c7b36 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -281,7 +281,11 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) static int mov_metadata_raw(MOVContext *c, AVIOContext *pb, unsigned len, const char *key) { - char *value = av_malloc(len + 1); + char *value; + // Check for overflow. + if (len >= INT_MAX) + return AVERROR(EINVAL); + value = av_malloc(len + 1); if (!value) return AVERROR(ENOMEM); avio_read(pb, value, len); @@ -385,7 +389,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); @@ -696,6 +700,9 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (atom.size < 16) return 0; + /* skip version and flags */ + avio_skip(pb, 4); + ff_mov_read_chan(c->fc, pb, st, atom.size - 4); return 0; @@ -830,9 +837,14 @@ 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); + av_log_ask_for_sample(c->fc, "unsupported version %d\n", version); return AVERROR_PATCHWELCOME; } avio_rb24(pb); /* flags */ @@ -877,7 +889,7 @@ 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 - if (c->time_scale > 0) + 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 */ @@ -1676,10 +1688,13 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) { sc->keyframe_absent = 1; + if (!st->need_parsing && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) + st->need_parsing = AVSTREAM_PARSE_HEADERS; 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); @@ -1798,6 +1813,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); @@ -1813,6 +1829,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; @@ -2012,6 +2032,11 @@ static void mov_build_index(MOVContext *mov, AVStream *st) rap_group_index++; } } + if (sc->keyframe_absent + && !sc->stps_count + && !rap_group_present + && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) + keyframe = 1; if (keyframe) distance = 0; sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample]; @@ -2510,7 +2535,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!sc->ctts_count && sc->sample_count) { /* Complement ctts table if moov atom doesn't have ctts atom. */ - ctts_data = av_malloc(sizeof(*sc->ctts_data)); + ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data)); if (!ctts_data) return AVERROR(ENOMEM); sc->ctts_data = ctts_data; @@ -2785,6 +2810,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVAtom a; int i; + if (c->atom_depth > 10) { + av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n"); + return AVERROR_INVALIDDATA; + } + c->atom_depth ++; + if (atom.size < 0) atom.size = INT64_MAX; while (total_size + 8 <= atom.size && !url_feof(pb)) { @@ -2801,11 +2832,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) { av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); avio_skip(pb, -8); + c->atom_depth --; return 0; } } total_size += 8; - if (a.size == 1) { /* 64 bit extended size */ + if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */ a.size = avio_rb64(pb) - 8; total_size += 8; } @@ -2837,20 +2869,25 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) int64_t start_pos = avio_tell(pb); int64_t left; int err = parse(c, pb, a); - if (err < 0) + if (err < 0) { + c->atom_depth --; return err; + } if (c->found_moov && c->found_mdat && ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || start_pos + a.size == avio_size(pb))) { if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) c->next_root_atom = start_pos + a.size; + c->atom_depth --; return 0; } left = a.size - avio_tell(pb) + start_pos; if (left > 0) /* skip garbage at atom end */ avio_skip(pb, left); - else if(left < 0) { - av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %"PRId64" in '%.4s'\n", -left, (char*)&a.type); + 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); } } @@ -2861,6 +2898,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (total_size < atom.size && atom.size < 0x7ffff) avio_skip(pb, atom.size - total_size); + c->atom_depth --; return 0; } @@ -3073,13 +3111,15 @@ static int mov_read_close(AVFormatContext *s) av_freep(&sc->drefs); if (sc->pb && sc->pb != s->pb) avio_close(sc->pb); + sc->pb = NULL; av_freep(&sc->chunk_offsets); - av_freep(&sc->keyframes); - av_freep(&sc->sample_sizes); - av_freep(&sc->stps_data); av_freep(&sc->stsc_data); + av_freep(&sc->sample_sizes); + av_freep(&sc->keyframes); av_freep(&sc->stts_data); + av_freep(&sc->stps_data); + av_freep(&sc->rap_group); } if (mov->dv_demux) { @@ -3199,7 +3239,7 @@ static int mov_read_header(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; MOVStreamContext *sc = st->priv_data; - if (st->duration) + if (st->duration > 0) st->codec->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration; } } diff --git a/libavformat/movenc.c b/libavformat/movenc.c index f08aa7e0db..d8f854c8a5 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1128,13 +1128,17 @@ 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->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0) + } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0) mov_write_dvc1_tag(pb, track); else if (track->vos_len > 0) mov_write_glbl_tag(pb, track); + if (track->enc->codec_id != AV_CODEC_ID_H264 && + track->enc->codec_id != AV_CODEC_ID_MPEG4 && + track->enc->codec_id != AV_CODEC_ID_DNXHD) + 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); @@ -1147,7 +1151,12 @@ static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track) { int64_t pos = avio_tell(pb); int frame_duration = av_rescale(track->timescale, track->enc->time_base.num, track->enc->time_base.den); - int nb_frames = (track->timescale + frame_duration/2) / frame_duration; + int nb_frames = 1.0/av_q2d(track->enc->time_base) + 0.5; + + if (nb_frames > 255) { + av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames); + return AVERROR(EINVAL); + } avio_wb32(pb, 0); /* size */ ffio_wfourcc(pb, "tmcd"); /* Data format */ @@ -2062,7 +2071,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); @@ -3157,6 +3167,14 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) memcpy(trk->vos_data, enc->extradata, trk->vos_len); } + if (enc->codec_id == AV_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 == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1) { /* from x264 or from bytestream h264 */ /* nal reformating needed */ @@ -3167,10 +3185,6 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } else { size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size); } - } else if (enc->codec_id == AV_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); } @@ -3628,6 +3642,9 @@ static int mov_write_header(AVFormatContext *s) }else{ track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels; } + if (st->codec->codec_id == AV_CODEC_ID_ILBC) { + track->audio_vbr = 1; + } if (track->mode != MODE_MOV && track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) { av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n", diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index c6d6987eaa..08f33241bd 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -37,10 +37,12 @@ typedef struct { int64_t filesize; + int64_t header_filesize; int xing_toc; int start_pad; int end_pad; -} MP3Context; + int is_cbr; +} MP3DecContext; /* mp3 read */ @@ -89,7 +91,7 @@ static int mp3_read_probe(AVProbeData *p) static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration) { int i; - MP3Context *mp3 = s->priv_data; + MP3DecContext *mp3 = s->priv_data; if (!filesize && !(filesize = avio_size(s->pb))) { @@ -113,13 +115,14 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { - MP3Context *mp3 = s->priv_data; + MP3DecContext *mp3 = s->priv_data; uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeHeader c; int vbrtag_size = 0; + int is_cbr; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) @@ -135,7 +138,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); - if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { + is_cbr = v == MKBETAG('I', 'n', 'f', 'o'); + if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) { v = avio_rb32(s->pb); if(v & XING_FLAG_FRAMES) frames = avio_rb32(s->pb); @@ -180,15 +184,18 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) if(frames) st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, st->time_base); - if(size && frames) + if (size && frames && !is_cbr) st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf); + mp3->is_cbr = is_cbr; + mp3->header_filesize = size; + return 0; } static int mp3_read_header(AVFormatContext *s) { - MP3Context *mp3 = s->priv_data; + MP3DecContext *mp3 = s->priv_data; AVStream *st; int64_t off; @@ -224,7 +231,7 @@ static int mp3_read_header(AVFormatContext *s) static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) { - MP3Context *mp3 = s->priv_data; + MP3DecContext *mp3 = s->priv_data; int ret, size; int64_t pos; @@ -271,29 +278,42 @@ static int check(AVFormatContext *s, int64_t pos) static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - MP3Context *mp3 = s->priv_data; - AVIndexEntry *ie; + MP3DecContext *mp3 = s->priv_data; + AVIndexEntry *ie, ie1; AVStream *st = s->streams[0]; int64_t ret = av_index_search_timestamp(st, timestamp, flags); int i, j; + int dir = (flags&AVSEEK_FLAG_BACKWARD) ? -1 : 1; - if (!mp3->xing_toc) { + if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) { + int64_t filesize = avio_size(s->pb); + int64_t duration; + if (filesize <= s->data_offset) + filesize = mp3->header_filesize; + filesize -= s->data_offset; + duration = av_rescale(st->duration, filesize, mp3->header_filesize - s->data_offset); + ie = &ie1; + timestamp = av_clip64(timestamp, 0, duration); + ie->timestamp = timestamp; + ie->pos = av_rescale(timestamp, filesize, duration) + s->data_offset; + } else if (mp3->xing_toc) { + if (ret < 0) + return ret; + + ie = &st->index_entries[ret]; + } else { st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; return -1; } - if (ret < 0) - return ret; - - ie = &st->index_entries[ret]; ret = avio_seek(s->pb, ie->pos, SEEK_SET); if (ret < 0) return ret; #define MIN_VALID 3 for(i=0; i<4096; i++) { - int64_t pos = ie->pos + i; + int64_t pos = ie->pos + i*dir; for(j=0; jpb, ie->pos + i, SEEK_SET); + ret = avio_seek(s->pb, ie->pos + i*dir, SEEK_SET); if (ret < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); @@ -317,11 +337,11 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, AVInputFormat ff_mp3_demuxer = { .name = "mp3", .long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"), - .priv_data_size = sizeof(MP3Context), .read_probe = mp3_read_probe, .read_header = mp3_read_header, .read_packet = mp3_read_packet, .read_seek = mp3_seek, + .priv_data_size = sizeof(MP3DecContext), .flags = AVFMT_GENERIC_INDEX, .extensions = "mp2,mp3,m2a", /* XXX: use probe */ }; diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index cc9f0d0919..245b507796 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -119,15 +119,16 @@ static int mp3_write_xing(AVFormatContext *s) { MP3Context *mp3 = s->priv_data; AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec; - int bitrate_idx; - int best_bitrate_idx = -1; - int best_bitrate_error= INT_MAX; - int xing_offset; - int32_t header, mask; - MPADecodeHeader c; - int srate_idx, ver = 0, i, channels; - int needed; - const char *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT; + int32_t header; + MPADecodeHeader mpah; + int srate_idx, i, channels; + int bitrate_idx; + int best_bitrate_idx = -1; + int best_bitrate_error = INT_MAX; + int xing_offset; + int ver = 0; + int bytes_needed; + const char *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT; if (!s->pb->seekable) return 0; @@ -159,28 +160,29 @@ static int mp3_write_xing(AVFormatContext *s) /* dummy MPEG audio header */ header = 0xffU << 24; // sync header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/ - header |= (srate_idx << 2) << 8; + header |= (srate_idx << 2) << 8; header |= channels << 6; - for (bitrate_idx=1; bitrate_idx<15; bitrate_idx++) { - int error; - avpriv_mpegaudio_decode_header(&c, header | (bitrate_idx << (4+8))); - error= FFABS(c.bit_rate - codec->bit_rate); - if(error < best_bitrate_error){ - best_bitrate_error= error; - best_bitrate_idx = bitrate_idx; + for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) { + int bit_rate = 1000 * avpriv_mpa_bitrate_tab[ver != 3][3 - 1][bitrate_idx]; + int error = FFABS(bit_rate - codec->bit_rate); + + if (error < best_bitrate_error) { + best_bitrate_error = error; + best_bitrate_idx = bitrate_idx; } } av_assert0(best_bitrate_idx >= 0); - for (bitrate_idx= best_bitrate_idx;; bitrate_idx++) { + for (bitrate_idx = best_bitrate_idx; ; bitrate_idx++) { + int32_t mask = bitrate_idx << (4 + 8); if (15 == bitrate_idx) return -1; - mask = bitrate_idx << (4+8); header |= mask; - avpriv_mpegaudio_decode_header(&c, header); - xing_offset=xing_offtbl[c.lsf == 1][c.nb_channels == 1]; - needed = 4 // header + + avpriv_mpegaudio_decode_header(&mpah, header); + xing_offset=xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1]; + bytes_needed = 4 // header + xing_offset + 4 // xing tag + 4 // frames/size/toc flags @@ -190,8 +192,9 @@ static int mp3_write_xing(AVFormatContext *s) + 24 ; - if (needed <= c.frame_size) + if (bytes_needed <= mpah.frame_size) break; + header &= ~mask; } @@ -202,7 +205,7 @@ static int mp3_write_xing(AVFormatContext *s) ffio_wfourcc(s->pb, "Xing"); avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames / size / TOC - mp3->size = c.frame_size; + mp3->size = mpah.frame_size; mp3->want=1; mp3->seen=0; mp3->pos=0; @@ -220,7 +223,7 @@ static int mp3_write_xing(AVFormatContext *s) avio_w8(s->pb, 0); avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12); - ffio_fill(s->pb, 0, c.frame_size - needed); + ffio_fill(s->pb, 0, mpah.frame_size - bytes_needed); return 0; } @@ -260,25 +263,25 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) MP3Context *mp3 = s->priv_data; if (pkt->data && pkt->size >= 4) { - MPADecodeHeader c; + MPADecodeHeader mpah; int av_unused base; - uint32_t head = AV_RB32(pkt->data); + uint32_t h; - if (ff_mpa_check_header(head) < 0) { + h = AV_RB32(pkt->data); + if (ff_mpa_check_header(h) == 0) { + avpriv_mpegaudio_decode_header(&mpah, h); + if (!mp3->initial_bitrate) + mp3->initial_bitrate = mpah.bit_rate; + if ((mpah.bit_rate == 0) || (mp3->initial_bitrate != mpah.bit_rate)) + mp3->has_variable_bitrate = 1; + } else { av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08X...) " - "is invalid, writing it anyway.\n", pkt->size, head); - return ff_raw_write_packet(s, pkt); + "is invalid, writing it anyway.\n", pkt->size, h); } - avpriv_mpegaudio_decode_header(&c, head); - - if (!mp3->initial_bitrate) - mp3->initial_bitrate = c.bit_rate; - if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate)) - mp3->has_variable_bitrate = 1; #ifdef FILTER_VBR_HEADERS /* filter out XING and INFO headers. */ - base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1]; + base = 4 + xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1]; if (base + 4 <= pkt->size) { uint32_t v = AV_RB32(pkt->data + base); diff --git a/libavformat/mpc.c b/libavformat/mpc.c index b0f6f533e1..a46919ba36 100644 --- a/libavformat/mpc.c +++ b/libavformat/mpc.c @@ -153,7 +153,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) } c->curbits = (curbits + size2) & 0x1F; - if ((ret = av_new_packet(pkt, size)) < 0) + if ((ret = av_new_packet(pkt, size + 4)) < 0) return ret; pkt->data[0] = curbits; diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index 011c7c8e64..f434c89227 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -57,7 +57,7 @@ typedef struct { static inline int64_t bs_get_v(const uint8_t **bs) { - int64_t v = 0; + uint64_t v = 0; int br = 0; int c; @@ -91,7 +91,7 @@ static int mpc8_probe(AVProbeData *p) size = bs_get_v(&bs); if (size < 2) return 0; - if (bs + size - 2 >= bs_end) + if (size >= bs_end - bs + 2) return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet if (header_found) { if (size < 11 || size > 28) @@ -108,7 +108,7 @@ static int mpc8_probe(AVProbeData *p) static inline int64_t gb_get_v(GetBitContext *gb) { - int64_t v = 0; + uint64_t v = 0; int bits = 0; while(get_bits1(gb) && bits < 64-7){ v <<= 7; @@ -139,6 +139,11 @@ 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){ @@ -146,7 +151,7 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) return; } if (size > INT_MAX/10 || size<=0) { - av_log(s, AV_LOG_ERROR, "Seek table size is invalid\n"); + av_log(s, AV_LOG_ERROR, "Bad seek table size\n"); return; } if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE))) @@ -211,6 +216,10 @@ static int mpc8_read_header(AVFormatContext *s) while(!url_feof(pb)){ pos = avio_tell(pb); mpc8_get_chunk_header(pb, &tag, &size); + if (size < 0) { + av_log(s, AV_LOG_ERROR, "Invalid chunk length\n"); + return AVERROR_INVALIDDATA; + } if(tag == TAG_STREAMHDR) break; mpc8_handle_chunk(s, tag, pos, size); diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index cc2fe7f495..c0bee2e64d 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -504,7 +504,7 @@ static int mpegps_read_packet(AVFormatContext *s, if(st->discard >= AVDISCARD_ALL) goto skip; if (startcode >= 0xa0 && startcode <= 0xaf) { - if (lpcm_header_len == 6) { + if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) { if (len < 6) goto skip; avio_skip(s->pb, 6); @@ -653,6 +653,7 @@ static int vobsub_read_header(AVFormatContext *s) st->id = stream_id; st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE; + avpriv_set_pts_info(st, 64, 1, 1000); av_dict_set(&st->metadata, "language", id, 0); av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id); header_parsed = 1; @@ -810,6 +811,21 @@ static int vobsub_read_seek(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags) { MpegDemuxContext *vobsub = s->priv_data; + + /* Rescale requested timestamps based on the first stream (timebase is the + * same for all subtitles stream within a .idx/.sub). Rescaling is done just + * like in avformat_seek_file(). */ + if (stream_index == -1 && s->nb_streams != 1) { + AVRational time_base = s->streams[0]->time_base; + ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base); + min_ts = av_rescale_rnd(min_ts, time_base.den, + time_base.num * (int64_t)AV_TIME_BASE, + AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + max_ts = av_rescale_rnd(max_ts, time_base.den, + time_base.num * (int64_t)AV_TIME_BASE, + AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX); + } + return ff_subtitles_queue_seek(&vobsub->q, s, stream_index, min_ts, ts, max_ts, flags); } diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c index b467bb5de5..2ff67dc517 100644 --- a/libavformat/mpegenc.c +++ b/libavformat/mpegenc.c @@ -1144,7 +1144,7 @@ static int mpeg_mux_end(AVFormatContext *ctx) #define OFFSET(x) offsetof(MpegMuxContext, x) #define E AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "muxrate", NULL, OFFSET(user_mux_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, + { "muxrate", NULL, OFFSET(user_mux_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, ((1<<22) - 1) * (8 * 50), E }, { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload), AV_OPT_TYPE_INT, {.i64 = 500000}, 0, INT_MAX, E}, { NULL }, }; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index a6e07fae9c..244eb40eae 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -208,9 +208,6 @@ static void clear_program(MpegTSContext *ts, unsigned int programid) static void clear_programs(MpegTSContext *ts) { - int i; - for(i=0; inb_prg; i++) - clear_avprogram(ts, ts->prg[i].id); av_freep(&ts->prg); ts->nb_prg=0; } @@ -1266,7 +1263,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; } @@ -1623,17 +1620,34 @@ 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); } } + + if (sid < 0) { + int i,j; + for (j=0; jstream->nb_programs; j++) { + for (i=0; inb_prg; i++) + if (ts->prg[i].id == ts->stream->programs[j]->id) + break; + if (i==ts->nb_prg) + clear_avprogram(ts, ts->stream->programs[j]->id); + } + } } static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) @@ -1679,7 +1693,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", diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 56b9d8506a..81316ce00e 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -130,6 +130,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) { @@ -242,7 +246,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; @@ -255,11 +259,11 @@ 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); @@ -277,6 +281,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 - 32) { + err = 1; + break; + } switch(st->codec->codec_id) { case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: @@ -308,6 +317,8 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) stream_type = STREAM_TYPE_PRIVATE_DATA; break; } + + *q++ = stream_type; put16(&q, 0xe000 | ts_st->pid); desc_length_ptr = q; @@ -340,6 +351,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 */ @@ -374,6 +389,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; @@ -399,8 +419,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 */ @@ -424,7 +453,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/mux.c b/libavformat/mux.c index c7e176abb3..72ac40ddc8 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -395,7 +395,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) return ret; } - if ((ret = init_pts(s) < 0)) + if ((ret = init_pts(s)) < 0) return ret; return 0; @@ -410,6 +410,12 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) av_dlog(s, "compute_pkt_fields2: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n", av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index); + if (pkt->duration < 0 && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) { + av_log(s, AV_LOG_WARNING, "Packet with invalid duration %d in stream %d\n", + pkt->duration, pkt->stream_index); + pkt->duration = 0; + } + /* duration field */ if (pkt->duration == 0) { ff_compute_frame_duration(&num, &den, st, NULL, pkt); @@ -490,13 +496,12 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) */ static inline int split_write_packet(AVFormatContext *s, AVPacket *pkt) { - int ret; - AVPacket spkt = *pkt; + int ret, did_split; - av_packet_split_side_data(&spkt); - ret = s->oformat->write_packet(s, &spkt); - spkt.data = NULL; - av_destruct_packet(&spkt); + did_split = av_packet_split_side_data(pkt); + ret = s->oformat->write_packet(s, pkt); + if (did_split) + av_packet_merge_side_data(pkt); return ret; } diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index bb1c5d0dd8..81ebb60a3a 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -354,7 +354,7 @@ static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt) AVStream *st = avctx->streams[mv->stream_index]; const AVIndexEntry *index; int frame = mv->frame[mv->stream_index]; - int ret; + int64_t ret; uint64_t pos; if (frame < st->nb_frames) { diff --git a/libavformat/mvi.c b/libavformat/mvi.c index 9184927a2f..99152f3c19 100644 --- a/libavformat/mvi.c +++ b/libavformat/mvi.c @@ -95,6 +95,12 @@ static int read_header(AVFormatContext *s) 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 bb5f4a7808..7b9daa20b7 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1562,11 +1562,13 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codec->bits_per_coded_sample = descriptor->bits_per_sample; if (descriptor->sample_rate.den > 0) { - avpriv_set_pts_info(st, 64, descriptor->sample_rate.den, descriptor->sample_rate.num); 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); + 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); } @@ -1591,8 +1593,10 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) } if (descriptor->extradata) { st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (st->codec->extradata) + if (st->codec->extradata) { memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size); + st->codec->extradata_size = descriptor->extradata_size; + } } else if(st->codec->codec_id == CODEC_ID_H264) { ff_generate_avci_extradata(st); } @@ -1845,6 +1849,8 @@ static int mxf_read_header(AVFormatContext *s) MXFContext *mxf = s->priv_data; KLVPacket klv; int64_t essence_offset = 0; + int64_t last_pos = -1; + uint64_t last_pos_index = 1; int ret; mxf->last_forward_tell = INT64_MAX; @@ -1860,7 +1866,12 @@ static int mxf_read_header(AVFormatContext *s) while (!url_feof(s->pb)) { const MXFMetadataReadTableEntry *metadata; - + if (avio_tell(s->pb) == last_pos) { + av_log(mxf->fc, AV_LOG_ERROR, "MXF structure loop detected\n"); + return AVERROR_INVALIDDATA; + } + if ((1ULL<<61) % last_pos_index++ == 0) + last_pos = avio_tell(s->pb); if (klv_read_packet(&klv, s->pb) < 0) { /* EOF - seek to previous partition or stop */ if(mxf_parse_handle_partition_or_eof(mxf) <= 0) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index cf9b77dd92..e9a870bf3e 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -76,6 +76,7 @@ typedef struct { int temporal_reordering; AVRational aspect_ratio; ///< display aspect ratio int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing + int video_bit_rate; } MXFStreamContext; typedef struct { @@ -976,13 +977,14 @@ static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st) static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) { AVIOContext *pb = s->pb; + MXFStreamContext *sc = st->priv_data; int profile_and_level = (st->codec->profile<<4) | st->codec->level; mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5); // bit rate mxf_write_local_tag(pb, 4, 0x8000); - avio_wb32(pb, st->codec->bit_rate); + avio_wb32(pb, sc->video_bit_rate); // profile and level mxf_write_local_tag(pb, 1, 0x8007); @@ -1705,14 +1707,15 @@ static int mxf_write_header(AVFormatContext *s) ret = av_timecode_init(&mxf->tc, rate, 0, 0, s); if (ret < 0) return ret; + sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate; if (s->oformat == &ff_mxf_d10_muxer) { - if (st->codec->bit_rate == 50000000) { + if (sc->video_bit_rate == 50000000) { if (mxf->time_base.den == 25) sc->index = 3; else sc->index = 5; - } else if (st->codec->bit_rate == 40000000) { + } else if (sc->video_bit_rate == 40000000) { if (mxf->time_base.den == 25) sc->index = 7; else sc->index = 9; - } else if (st->codec->bit_rate == 30000000) { + } else if (sc->video_bit_rate == 30000000) { if (mxf->time_base.den == 25) sc->index = 11; else sc->index = 13; } else { @@ -1721,7 +1724,7 @@ static int mxf_write_header(AVFormatContext *s) } mxf->edit_unit_byte_count = KAG_SIZE; // system element - mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate * + mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate * mxf->time_base.num / (8*mxf->time_base.den); mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4; @@ -1855,7 +1858,8 @@ static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacke { MXFContext *mxf = s->priv_data; AVIOContext *pb = s->pb; - int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num / + MXFStreamContext *sc = st->priv_data; + int packet_size = (uint64_t)sc->video_bit_rate*mxf->time_base.num / (8*mxf->time_base.den); // frame size int pad; diff --git a/libavformat/nut.c b/libavformat/nut.c index 62a650dbed..699e90a2b8 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -210,10 +210,16 @@ int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b){ return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32); } -void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){ +int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){ Syncpoint *sp= av_mallocz(sizeof(Syncpoint)); struct AVTreeNode *node = av_tree_node_alloc(); + if (!sp || !node) { + av_freep(&sp); + av_freep(&node); + return AVERROR(ENOMEM); + } + nut->sp_count++; sp->pos= pos; @@ -224,6 +230,8 @@ void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){ av_free(sp); av_free(node); } + + return 0; } static int enu_free(void *opaque, void *elem) diff --git a/libavformat/nut.h b/libavformat/nut.h index ab31c27429..f38406eff8 100644 --- a/libavformat/nut.h +++ b/libavformat/nut.h @@ -123,7 +123,7 @@ void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val); int64_t ff_lsb2full(StreamContext *stream, int64_t lsb); int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b); int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b); -void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts); +int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts); void ff_nut_free_sp(NUTContext *nut); extern const Dispositions ff_nut_dispositions[]; diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index f260a3e4fd..c44e7b1e16 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -546,6 +546,7 @@ static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr) AVIOContext *bc = s->pb; int64_t end; uint64_t tmp; + int ret; nut->last_syncpoint_pos = avio_tell(bc) - 8; @@ -567,7 +568,9 @@ static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr) *ts = tmp / nut->time_base_count * av_q2d(nut->time_base[tmp % nut->time_base_count]) * AV_TIME_BASE; - ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts); + + if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts)) < 0) + return ret; return 0; } diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 46711528a0..7924530386 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -584,8 +584,15 @@ static int write_index(NUTContext *nut, AVIOContext *bc) { int64_t last_pts= -1; int j, k; for (j=0; jsp_count; j++) { - int flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count); + int flag; int n = 0; + + if (j && nus->keyframe_pts[j] == nus->keyframe_pts[j-1]) { + av_log(nut->avf, AV_LOG_WARNING, "Multiple keyframes with same PTS\n"); + nus->keyframe_pts[j] = AV_NOPTS_VALUE; + } + + flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count); for (; jsp_count && (nus->keyframe_pts[j] != AV_NOPTS_VALUE) == flag; j++) n++; @@ -858,7 +865,8 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt) ff_put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos) >> 4 : 0); put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE); - ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts); + if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts)) < 0) + return ret; if ((1ll<<60) % nut->sp_count == 0) for (i=0; inb_streams; i++) { diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index c3291cfbd4..0d283b15c5 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -102,6 +102,7 @@ static int ogg_restore(AVFormatContext *s, int discard) av_free(ogg->streams[i].buf); avio_seek(bc, ost->pos, SEEK_SET); + ogg->page_pos = -1; ogg->curidx = ost->curidx; ogg->nstreams = ost->nstreams; ogg->streams = av_realloc(ogg->streams, @@ -146,6 +147,7 @@ static int ogg_reset(AVFormatContext *s) } } + ogg->page_pos = -1; ogg->curidx = -1; return 0; @@ -183,6 +185,9 @@ static int ogg_replace_stream(AVFormatContext *s, uint32_t serial) os = &ogg->streams[0]; + os->serial = serial; + return 0; + buf = os->buf; bufsize = os->bufsize; codec = os->codec; @@ -297,6 +302,12 @@ static int ogg_read_page(AVFormatContext *s, int *sid) sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S') break; + if(!i && bc->seekable && ogg->page_pos > 0) { + memset(sync, 0, 4); + avio_seek(bc, ogg->page_pos+4, SEEK_SET); + ogg->page_pos = -1; + } + c = avio_r8(bc); if (url_feof(bc)) @@ -335,6 +346,7 @@ static int ogg_read_page(AVFormatContext *s, int *sid) } os = ogg->streams + idx; + ogg->page_pos = os->page_pos = avio_tell(bc) - 27; if (os->psize > 0) @@ -559,6 +571,7 @@ static int ogg_get_length(AVFormatContext *s) ogg_save(s); avio_seek(s->pb, end, SEEK_SET); + ogg->page_pos = -1; while (!ogg_read_page(s, &i)) { if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 && @@ -599,6 +612,23 @@ static int ogg_get_length(AVFormatContext *s) return 0; } +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; @@ -722,19 +752,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) { @@ -751,6 +768,11 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index, && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) { if (i == stream_index) { struct ogg_stream *os = ogg->streams + stream_index; + // Dont trust the last timestamps of a ogm video + if ( (os->flags & OGG_FLAG_EOS) + && !(os->flags & OGG_FLAG_BOS) + && os->codec == &ff_ogm_video_codec) + continue; pts = ogg_calc_pts(s, i, NULL); ogg_validate_keyframe(s, i, pstart, psize); if (os->pflags & AV_PKT_FLAG_KEY) { diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h index febf8cb642..e9a300dd9e 100644 --- a/libavformat/oggdec.h +++ b/libavformat/oggdec.h @@ -55,6 +55,7 @@ struct ogg_codec { * Number of expected headers */ int nb_header; + void (*cleanup)(AVFormatContext *s, int idx); }; struct ogg_stream { @@ -99,6 +100,7 @@ struct ogg { int nstreams; int headers; int curidx; + int64_t page_pos; ///< file offset of the current page struct ogg_state *state; }; diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c index a3caac0e15..01e6c7345e 100644 --- a/libavformat/oggparseogm.c +++ b/libavformat/oggparseogm.c @@ -38,34 +38,35 @@ 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; uint32_t size; - 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 = AV_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); @@ -74,25 +75,30 @@ ogm_header(AVFormatContext *s, int idx) st->need_parsing = AVSTREAM_PARSE_FULL; } - size = bytestream_get_le32(&p); + size = bytestream2_get_le32(&p); size = FFMIN(size, os->psize); - 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); avpriv_set_pts_info(st, 64, time_unit, spu * 10000000); } 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 = time_unit ? spu * 10000000 / time_unit : 0; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); if (size >= 56 && st->codec->codec_id == AV_CODEC_ID_AAC) { - p += 4; + bytestream2_skip(&p, 4); size -= 4; } if (size > 52) { @@ -100,12 +106,13 @@ ogm_header(AVFormatContext *s, int idx) size -= 52; st->codec->extradata_size = size; st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - bytestream_get_buffer(&p, st->codec->extradata, size); + bytestream2_get_buffer(&p, st->codec->extradata, size); } } - } 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/oggparseopus.c b/libavformat/oggparseopus.c index 0e8f1ca5bb..c24a062c92 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -36,11 +36,11 @@ struct oggopus_private { static int opus_header(AVFormatContext *avf, int idx) { - struct ogg *ogg = avf->priv_data; - struct ogg_stream *os = &ogg->streams[idx]; - AVStream *st = avf->streams[idx]; + struct ogg *ogg = avf->priv_data; + struct ogg_stream *os = &ogg->streams[idx]; + AVStream *st = avf->streams[idx]; struct oggopus_private *priv = os->private; - uint8_t *packet = os->buf + os->pstart; + uint8_t *packet = os->buf + os->pstart; uint8_t *extradata; if (!priv) { @@ -48,22 +48,24 @@ static int opus_header(AVFormatContext *avf, int idx) if (!priv) return AVERROR(ENOMEM); } + if (os->flags & OGG_FLAG_BOS) { if (os->psize < OPUS_HEAD_SIZE || (AV_RL8(packet + 8) & 0xF0) != 0) return AVERROR_INVALIDDATA; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_OPUS; - st->codec->channels = AV_RL8 (packet + 9); - priv->pre_skip = AV_RL16(packet + 10); - /*orig_sample_rate = AV_RL32(packet + 12);*/ - /*gain = AV_RL16(packet + 16);*/ - /*channel_map = AV_RL8 (packet + 18);*/ + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = AV_CODEC_ID_OPUS; + st->codec->channels = AV_RL8 (packet + 9); + priv->pre_skip = AV_RL16(packet + 10); + /*orig_sample_rate = AV_RL32(packet + 12);*/ + /*gain = AV_RL16(packet + 16);*/ + /*channel_map = AV_RL8 (packet + 18);*/ extradata = av_malloc(os->psize + FF_INPUT_BUFFER_PADDING_SIZE); if (!extradata) return AVERROR(ENOMEM); + memcpy(extradata, packet, os->psize); - st->codec->extradata = extradata; + st->codec->extradata = extradata; st->codec->extradata_size = os->psize; st->codec->sample_rate = 48000; @@ -79,21 +81,23 @@ static int opus_header(AVFormatContext *avf, int idx) priv->need_comments--; return 1; } + return 0; } static int opus_packet(AVFormatContext *avf, int idx) { - struct ogg *ogg = avf->priv_data; - struct ogg_stream *os = &ogg->streams[idx]; - AVStream *st = avf->streams[idx]; + struct ogg *ogg = avf->priv_data; + struct ogg_stream *os = &ogg->streams[idx]; + AVStream *st = avf->streams[idx]; struct oggopus_private *priv = os->private; - uint8_t *packet = os->buf + os->pstart; + uint8_t *packet = os->buf + os->pstart; unsigned toc, toc_config, toc_count, frame_size, nb_frames = 1; if (!os->psize) return AVERROR_INVALIDDATA; - toc = *packet; + + toc = *packet; toc_config = toc >> 3; toc_count = toc & 3; frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) : @@ -106,12 +110,14 @@ static int opus_packet(AVFormatContext *avf, int idx) } else if (toc_count) { nb_frames = 2; } + os->pduration = frame_size * nb_frames; if (os->lastpts != AV_NOPTS_VALUE) { if (st->start_time == AV_NOPTS_VALUE) st->start_time = os->lastpts; priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip; } + priv->cur_dts += os->pduration; if ((os->flags & OGG_FLAG_EOS)) { int64_t skip = priv->cur_dts - os->granule + priv->pre_skip; @@ -123,13 +129,14 @@ static int opus_packet(AVFormatContext *avf, int idx) os->pduration); } } + return 0; } const struct ogg_codec ff_opus_codec = { - .name = "Opus", - .magic = "OpusHead", - .magicsize = 8, - .header = opus_header, - .packet = opus_packet, + .name = "Opus", + .magic = "OpusHead", + .magicsize = 8, + .header = opus_header, + .packet = opus_packet, }; diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c index f9ad701145..79c018da66 100644 --- a/libavformat/oggparseskeleton.c +++ b/libavformat/oggparseskeleton.c @@ -37,6 +37,9 @@ static int skeleton_header(AVFormatContext *s, int idx) strcpy(st->codec->codec_name, "skeleton"); st->codec->codec_type = AVMEDIA_TYPE_DATA; + if ((os->flags & OGG_FLAG_EOS) && os->psize == 0) + return 1; + if (os->psize < 8) return -1; @@ -74,12 +77,16 @@ static int skeleton_header(AVFormatContext *s, int idx) target_idx = ogg_find_stream(ogg, AV_RL32(buf+12)); start_granule = AV_RL64(buf+36); - if (os->start_granule != OGG_NOGRANULE_VALUE) { - av_log_missing_feature(s, - "Multiple fisbone for the same stream", 0); + if (target_idx < 0) { + av_log(s, AV_LOG_WARNING, "Serial number in fisbone doesn't match any stream\n"); return 1; } - if (target_idx >= 0 && start_granule != OGG_NOGRANULE_VALUE) { + os = ogg->streams + target_idx; + if (os->start_granule != OGG_NOGRANULE_VALUE) { + av_log(s, AV_LOG_WARNING, "Multiple fisbone for the same stream\n"); + return 1; + } + if (start_granule != OGG_NOGRANULE_VALUE) { os->start_granule = start_granule; } } diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index 7e8f6cede3..371c798a50 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -192,6 +192,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) @@ -202,15 +212,15 @@ vorbis_header (AVFormatContext * s, int idx) struct oggvorbis_private *priv; int pkt_type = os->buf[os->pstart]; - if (!(pkt_type & 1)) - return os->private ? 0 : -1; - if (!os->private) { os->private = av_mallocz(sizeof(struct oggvorbis_private)); if (!os->private) return -1; } + if (!(pkt_type & 1)) + return 0; + if (os->psize < 1 || pkt_type > 5) return -1; @@ -373,5 +383,6 @@ const struct ogg_codec ff_vorbis_codec = { .magicsize = 7, .header = vorbis_header, .packet = vorbis_packet, + .cleanup= vorbis_cleanup, .nb_header = 3, }; diff --git a/libavformat/oma.c b/libavformat/oma.c index 9e4bfbdd77..fc926bf8ba 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[8] = { 320, 441, 480, 882, 960, 0, 0, 0}; +const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0 }; const AVCodecTag ff_oma_codec_tags[] = { { AV_CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, diff --git a/libavformat/omadec.c b/libavformat/omadec.c index 8d29675c1c..5263bc4d5d 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -112,13 +112,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 */ @@ -139,35 +144,45 @@ 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"); taglen = AV_RB32(&enc_header[pos+32]); datalen = AV_RB32(&enc_header[pos+36]) >> 4; - if(pos + (uint64_t)taglen + (((uint64_t)datalen)<<4) + 44 > size) + pos += 44; + if (size - pos < taglen) return -1; - pos += 44 + taglen; + pos += taglen; + + if (pos + (((uint64_t)datalen) << 4) > size) + 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; } @@ -218,9 +233,8 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) av_log(s, AV_LOG_ERROR, "Invalid encryption header\n"); return -1; } - if ( OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize - || OMA_ENC_HEADER_SIZE + 48 > geob->datasize - ) { + if (OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize || + OMA_ENC_HEADER_SIZE + 48 > geob->datasize) { av_log(s, AV_LOG_ERROR, "Too little GEOB data\n"); return AVERROR_INVALIDDATA; } @@ -236,7 +250,7 @@ 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 < FF_ARRAY_ELEMS(leaf_table); i += 2) { @@ -244,7 +258,8 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) 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 >= FF_ARRAY_ELEMS(leaf_table)) { @@ -309,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); @@ -340,9 +359,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: @@ -377,14 +401,24 @@ 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 <= 0) - return AVERROR(EIO); + if (ret < packet_size) + pkt->flags |= AV_PKT_FLAG_CORRUPT; + + if (ret < 0) + return ret; + if (!ret) + return AVERROR_EOF; 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, (ret >> 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; @@ -421,23 +455,26 @@ static int oma_read_probe(AVProbeData *p) static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { OMAContext *oc = s->priv_data; + int err = ff_pcm_read_seek(s, stream_index, timestamp, flags); - ff_pcm_read_seek(s, stream_index, timestamp, flags); + if (!oc->encrypted) + return err; - 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; - } - } + /* 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/paf.c b/libavformat/paf.c index 09786eb34f..09aefe6770 100644 --- a/libavformat/paf.c +++ b/libavformat/paf.c @@ -233,10 +233,11 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) p->current_frame_block++; } - size = p->video_size - p->frames_offset_table[p->current_frame]; - if (size < 1) + if (p->frames_offset_table[p->current_frame] >= p->video_size) return AVERROR_INVALIDDATA; + size = p->video_size - p->frames_offset_table[p->current_frame]; + if (av_new_packet(pkt, size) < 0) return AVERROR(ENOMEM); diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c index 2ea37ef030..cfac3344c4 100644 --- a/libavformat/pmpdec.c +++ b/libavformat/pmpdec.c @@ -125,9 +125,10 @@ static int pmp_packet(AVFormatContext *s, AVPacket *pkt) int num_packets; pmp->audio_packets = avio_r8(pb); if (!pmp->audio_packets) { - av_log_ask_for_sample(s, "0 audio packets\n"); - return AVERROR_PATCHWELCOME; + av_log(s, AV_LOG_ERROR, "No audio packets.\n"); + return AVERROR_INVALIDDATA; } + num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1; avio_skip(pb, 8); pmp->current_packet = 0; diff --git a/libavformat/r3d.c b/libavformat/r3d.c index 35da81eff1..1c673e3720 100644 --- a/libavformat/r3d.c +++ b/libavformat/r3d.c @@ -87,7 +87,7 @@ static int r3d_read_red1(AVFormatContext *s) framerate.num = avio_rb16(s->pb); framerate.den = avio_rb16(s->pb); - if (framerate.num && framerate.den) { + if (framerate.num > 0 && framerate.den > 0) { #if FF_API_R_FRAME_RATE st->r_frame_rate = #endif @@ -285,6 +285,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 573e4179cd..02bf1e5962 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -736,6 +736,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 == AV_CODEC_ID_AAC_LATM) { /* channels and sample_rate values are those prior to applying SBR and/or PS */ codec->channels = 0; @@ -817,7 +822,13 @@ int ff_read_riff_info(AVFormatContext *s, int64_t size) chunk_code = avio_rl32(pb); chunk_size = avio_rl32(pb); - + if (url_feof(pb)) { + if (chunk_code || chunk_size) { + av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n"); + return AVERROR_INVALIDDATA; + } + return AVERROR_EOF; + } if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { avio_seek(pb, -9, SEEK_CUR); chunk_code = avio_rl32(pb); @@ -833,6 +844,10 @@ int ff_read_riff_info(AVFormatContext *s, int64_t size) if (!chunk_code) { if (chunk_size) avio_skip(pb, chunk_size); + else if (pb->eof_reached) { + av_log(s, AV_LOG_WARNING, "truncated file\n"); + return AVERROR_EOF; + } continue; } diff --git a/libavformat/rl2.c b/libavformat/rl2.c index 800e12edbe..c72b6655d0 100644 --- a/libavformat/rl2.c +++ b/libavformat/rl2.c @@ -107,6 +107,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 3b476ff93c..38f101fc53 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -94,13 +94,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); } } @@ -133,7 +134,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, avio_skip(pb, 8); bytes_per_minute = avio_rb16(pb); avio_skip(pb, 4); - 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); @@ -292,7 +293,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; @@ -307,6 +308,9 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, int64_t codec_pos; int ret; + if (codec_data_size < 0) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); v = avio_rb32(pb); @@ -374,8 +378,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->avg_frame_rate.den, &st->avg_frame_rate.num, - 0x10000, fps, (1 << 30) - 1); + if (fps > 0) { + av_reduce(&st->avg_frame_rate.den, &st->avg_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; + } #if FF_API_R_FRAME_RATE st->r_frame_rate = st->avg_frame_rate; #endif @@ -515,7 +524,7 @@ static int rm_read_header(AVFormatContext *s) 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); @@ -995,6 +1004,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"), @@ -1004,6 +1025,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 a96c42933d..d58a049172 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) @@ -392,6 +396,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 04724f7b9c..d1c38192c7 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -145,25 +145,25 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size, { uint8_t 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; int ret; - 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) { @@ -171,21 +171,21 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size, } 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); } } @@ -199,36 +199,36 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size, timestamp += prev_pkt[channel_id].timestamp; if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp, - data_size)) < 0) + size)) < 0) return ret; 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) { if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker ff_rtmp_packet_destroy(p); return ret; } - size++; + written++; if (t != (0xC0 + channel_id)) return -1; } } - return size; + return written; } int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, @@ -237,7 +237,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; int ret; pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp; @@ -246,7 +246,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; @@ -270,7 +270,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); @@ -281,7 +281,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; @@ -292,20 +292,20 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0) return ret; - 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); if ((ret = ffurl_write(h, pkt->data + off, towrite)) < 0) return ret; off += towrite; - if (off < pkt->data_size) { + if (off < pkt->size) { uint8_t marker = 0xC0 | pkt->channel_id; if ((ret = ffurl_write(h, &marker, 1)) < 0) return ret; - size++; + written++; } } - return size; + return written; } int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, @@ -316,7 +316,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; @@ -331,7 +331,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) @@ -356,11 +356,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; } @@ -389,7 +389,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)) { @@ -410,7 +410,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; } @@ -440,7 +440,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) @@ -459,7 +459,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); @@ -472,22 +472,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; } @@ -503,9 +502,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); @@ -520,8 +519,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 a9422954f5..421ad37934 100644 --- a/libavformat/rtmppkt.h +++ b/libavformat/rtmppkt.h @@ -81,7 +81,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; /** @@ -282,6 +282,13 @@ int ff_amf_read_string(GetByteContext *gbc, uint8_t *str, */ int ff_amf_read_null(GetByteContext *gbc); +/** + * 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 diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 1132ab6941..d5ad463165 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -186,7 +186,7 @@ static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset, int ret; int i; - bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset); + bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset); if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0) return ret; @@ -224,7 +224,7 @@ static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track) double pkt_id; int len; - bytestream2_init(&gbc, pkt->data, pkt->data_size); + bytestream2_init(&gbc, pkt->data, pkt->size); if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0) goto fail; @@ -385,7 +385,7 @@ static int gen_connect(URLContext *s, RTMPContext *rt) } } - pkt.data_size = p - pkt.data; + pkt.size = p - pkt.data; return rtmp_send_packet(rt, &pkt, 1); } @@ -406,7 +406,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) rt->prev_pkt[1])) < 0) return ret; cp = pkt.data; - bytestream2_init(&gbc, cp, pkt.data_size); + bytestream2_init(&gbc, cp, pkt.size); if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) { av_log(s, AV_LOG_ERROR, "Unable to read command string\n"); ff_rtmp_packet_destroy(&pkt); @@ -437,7 +437,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) return ret; p = pkt.data; bytestream_put_be32(&p, rt->server_bw); - pkt.data_size = p - pkt.data; + pkt.size = p - pkt.data; ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -450,7 +450,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) p = pkt.data; bytestream_put_be32(&p, rt->server_bw); bytestream_put_byte(&p, 2); // dynamic - pkt.data_size = p - pkt.data; + pkt.size = p - pkt.data; ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -512,7 +512,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) ff_amf_write_number(&p, 0); ff_amf_write_object_end(&p); - pkt.data_size = p - pkt.data; + pkt.size = p - pkt.data; ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -527,7 +527,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) ff_amf_write_number(&p, 0); ff_amf_write_null(&p); ff_amf_write_number(&p, 8192); - pkt.data_size = p - pkt.data; + pkt.size = p - pkt.data; ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -742,9 +742,9 @@ static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt) uint8_t *p; int ret; - if (ppkt->data_size < 6) { + if (ppkt->size < 6) { av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n", - ppkt->data_size); + ppkt->size); return AVERROR_INVALIDDATA; } @@ -1418,10 +1418,10 @@ static int handle_chunk_size(URLContext *s, RTMPPacket *pkt) RTMPContext *rt = s->priv_data; int ret; - if (pkt->data_size < 4) { + if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, "Too short chunk size change packet (%d)\n", - pkt->data_size); + pkt->size); return AVERROR_INVALIDDATA; } @@ -1451,9 +1451,9 @@ static int handle_ping(URLContext *s, RTMPPacket *pkt) RTMPContext *rt = s->priv_data; int t, ret; - if (pkt->data_size < 2) { + if (pkt->size < 2) { av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n", - pkt->data_size); + pkt->size); return AVERROR_INVALIDDATA; } @@ -1477,10 +1477,10 @@ static int handle_client_bw(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; - 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 AVERROR_INVALIDDATA; } @@ -1501,10 +1501,10 @@ static int handle_server_bw(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; - if (pkt->data_size < 4) { + if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, "Too short server bandwidth report packet (%d)\n", - pkt->data_size); + pkt->size); return AVERROR_INVALIDDATA; } @@ -1704,7 +1704,7 @@ static int handle_connect_error(URLContext *s, const char *desc) static int handle_invoke_error(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; - const uint8_t *data_end = pkt->data + pkt->data_size; + const uint8_t *data_end = pkt->data + pkt->size; char *tracked_method = NULL; int level = AV_LOG_ERROR; uint8_t tmpstr[256]; @@ -1752,7 +1752,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt) GetByteContext gbc; int ret; - bytestream2_init(&gbc, p, pkt->data_size); + bytestream2_init(&gbc, p, pkt->size); if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) { av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n"); @@ -1804,7 +1804,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt) return ret; } pp = spkt.data; - bytestream2_init_writer(&pbc, pp, spkt.data_size); + bytestream2_init_writer(&pbc, pp, spkt.size); bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin bytestream2_put_be32(&pbc, rt->nb_streamid); ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size, @@ -1863,7 +1863,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt) * if a client creates more than 2^32 - 2 streams. */ } } - spkt.data_size = pp - spkt.data; + spkt.size = pp - spkt.data; ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&spkt); @@ -1884,7 +1884,7 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt) return ret; } - if (!memcmp(tracked_method, "connect", 7)) { + if (!strcmp(tracked_method, "connect")) { if (!rt->is_input) { if ((ret = gen_release_stream(s, rt)) < 0) goto fail; @@ -1910,7 +1910,7 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt) goto fail; } } - } else if (!memcmp(tracked_method, "createStream", 12)) { + } else if (!strcmp(tracked_method, "createStream")) { //extract a number from the result if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) { av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n"); @@ -1937,7 +1937,7 @@ fail: static int handle_invoke_status(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; - const uint8_t *data_end = pkt->data + pkt->data_size; + const uint8_t *data_end = pkt->data + pkt->size; const uint8_t *ptr = pkt->data + 11; uint8_t tmpstr[256]; int i, t; @@ -1972,24 +1972,24 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt) int ret = 0; //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")) { if ((ret = handle_invoke_error(s, pkt)) < 0) return ret; - } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { + } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) { if ((ret = handle_invoke_result(s, pkt)) < 0) return ret; - } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) { + } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) { if ((ret = handle_invoke_status(s, pkt)) < 0) return ret; - } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) { + } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) { if ((ret = gen_check_bw(s, rt)) < 0) return ret; - } else if (!memcmp(pkt->data, "\002\000\015releaseStream", 16) || - !memcmp(pkt->data, "\002\000\011FCPublish", 12) || - !memcmp(pkt->data, "\002\000\007publish", 10) || - !memcmp(pkt->data, "\002\000\010_checkbw", 11) || - !memcmp(pkt->data, "\002\000\014createStream", 15)) { - if (ret = send_invoke_response(s, pkt) < 0) + } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") || + ff_amf_match_string(pkt->data, pkt->size, "FCPublish") || + ff_amf_match_string(pkt->data, pkt->size, "publish") || + ff_amf_match_string(pkt->data, pkt->size, "_checkbw") || + ff_amf_match_string(pkt->data, pkt->size, "createStream")) { + if ((ret = send_invoke_response(s, pkt)) < 0) return ret; } @@ -2011,7 +2011,7 @@ static int handle_notify(URLContext *s, RTMPPacket *pkt) { unsigned datatowritelength; p = pkt->data; - bytestream2_init(&gbc, p, pkt->data_size); + bytestream2_init(&gbc, p, pkt->size); if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer), &stringlen)) return AVERROR_INVALIDDATA; @@ -2125,7 +2125,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) @@ -2168,24 +2168,25 @@ 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; @@ -2200,14 +2201,14 @@ static int get_packet(URLContext *s, int for_header) } 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; @@ -2217,9 +2218,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; } @@ -2234,7 +2235,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) ret = gen_fcunpublish_stream(h, rt); @@ -2367,16 +2368,20 @@ reconnect: fname = strchr(p + 1, '/'); if (!fname || (c && c < fname)) { fname = p + 1; - av_strlcpy(rt->app, path + 1, p - path); + av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH)); } else { fname++; - av_strlcpy(rt->app, path + 1, fname - path - 1); + av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH)); } } } if (old_app) { // The name of application has been defined by the user, override it. + if (strlen(old_app) >= APP_MAX_LENGTH) { + ret = AVERROR(EINVAL); + goto fail; + } av_free(rt->app); rt->app = old_app; } @@ -2439,7 +2444,7 @@ reconnect: if ((ret = gen_connect(s, rt)) < 0) goto fail; } else { - if (read_connect(s, s->priv_data) < 0) + if ((ret = read_connect(s, s->priv_data)) < 0) goto fail; rt->is_input = 1; } diff --git a/libavformat/rtp.c b/libavformat/rtp.c index ab0af11cbb..c8eebac5cb 100644 --- a/libavformat/rtp.c +++ b/libavformat/rtp.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include "libavutil/opt.h" #include "avformat.h" #include "rtp.h" @@ -107,8 +107,8 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt, /* static payload type */ for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i) if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) { - if (codec->codec_id == AV_CODEC_ID_H263 && (!fmt || - !fmt->oformat->priv_class || + if (codec->codec_id == AV_CODEC_ID_H263 && (!fmt || !fmt->oformat || + !fmt->oformat->priv_class || !fmt->priv_data || !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190"))) continue; /* G722 has 8000 as nominal rate even if the sample rate is 16000, diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c index df7410d0c8..70d68ce534 100644 --- a/libavformat/rtpenc_chain.c +++ b/libavformat/rtpenc_chain.c @@ -64,7 +64,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, /* Get the payload type from the codec */ if (st->id < RTP_PT_PRIVATE) rtpctx->streams[0]->id = - ff_rtp_get_payload_type(rtpctx, st->codec, idx); + ff_rtp_get_payload_type(s, st->codec, idx); else rtpctx->streams[0]->id = st->id; diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c index 68f497590b..b6c16e17d8 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/sdp.c b/libavformat/sdp.c index cdc3e212ef..3b9079c62e 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -402,7 +402,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, switch (c->codec_id) { case AV_CODEC_ID_H264: { int mode = 1; - if (fmt && fmt->oformat->priv_class && + if (fmt && fmt->oformat && fmt->oformat->priv_class && av_opt_flag_is_set(fmt->priv_data, "rtpflags", "h264_mode0")) mode = 0; if (c->extradata_size) { diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index a33ad858f5..506244d185 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -76,13 +76,23 @@ 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) { FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; unsigned char scratch[256]; - int i; + int i, ret; unsigned int data_offset; unsigned int audio_frame_counter; @@ -112,6 +122,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_channels > 0) film->audio_type = AV_CODEC_ID_ADPCM_ADX; @@ -209,12 +224,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; @@ -235,6 +254,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, @@ -315,16 +337,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"), diff --git a/libavformat/segment.c b/libavformat/segment.c index efc35c8bf5..76616f8a0b 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -656,12 +656,6 @@ fail: if (pkt->stream_index == seg->reference_stream_index) seg->frame_count++; - if (ret < 0) { - if (seg->list) - avio_close(seg->list_pb); - avformat_free_context(oc); - } - return ret; } diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c index b0b582d719..a4f502a17e 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]; @@ -176,15 +176,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; @@ -200,6 +198,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) { @@ -236,6 +239,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 883a2b7254..1af3111f99 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -210,7 +210,8 @@ static int smacker_read_header(AVFormatContext *s) /* load trees to extradata, they will be unpacked by decoder */ - st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE); + 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); @@ -276,7 +277,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) } else if(t & 0x40){ /* copy with offset */ off = avio_r8(s->pb); j = (t & 0x3F) + 1; - if (off + j > 0xff) { + 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); @@ -305,12 +306,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++; @@ -326,7 +329,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); @@ -342,6 +345,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/srtdec.c b/libavformat/srtdec.c index 809d1d064a..76e06e4165 100644 --- a/libavformat/srtdec.c +++ b/libavformat/srtdec.c @@ -100,6 +100,8 @@ static int srt_read_header(AVFormatContext *s) pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2); if (pts != AV_NOPTS_VALUE) { int len = buf.len - (ptr - buf.str); + if (len <= 0) + continue; sub = ff_subtitles_queue_insert(&srt->q, ptr, len, 0); if (!sub) { res = AVERROR(ENOMEM); diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index 546261605f..339e2c787f 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -108,7 +108,8 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st for (i = 0; i < q->nb_subs; i++) { int64_t pts = q->subs[i].pts; uint64_t ts_diff = FFABS(pts - ts); - if (pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) { + if ((stream_index == -1 || q->subs[i].stream_index == stream_index) && + pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) { min_ts_diff = ts_diff; idx = i; } @@ -118,13 +119,25 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st /* look back in the latest subtitles for overlapping subtitles */ ts_selected = q->subs[idx].pts; for (i = idx - 1; i >= 0; i--) { - if (q->subs[i].duration <= 0) + int64_t pts = q->subs[i].pts; + if (q->subs[i].duration <= 0 || + (stream_index != -1 && q->subs[i].stream_index != stream_index)) continue; - if (q->subs[i].pts > ts_selected - q->subs[i].duration) + if (pts >= min_ts && pts > ts_selected - q->subs[i].duration) idx = i; else break; } + + /* If the queue is used to store multiple subtitles streams (like with + * VobSub) and the stream index is not specified, we need to make sure + * to focus on the smallest file position offset for a same timestamp; + * queue is ordered by pts and then filepos, so we can take the first + * entry for a given timestamp. */ + if (stream_index == -1) + while (idx > 0 && q->subs[idx - 1].pts == q->subs[idx].pts) + idx--; + q->current_sub_idx = idx; } return 0; diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 8fb4aeb37a..2e3731210f 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -282,6 +282,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) const int bmp_fmt = avio_r8(pb); const int width = avio_rl16(pb); const int height = avio_rl16(pb); + int pix_fmt; len -= 2+1+2+2; @@ -346,17 +347,21 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) avpriv_set_pts_info(vst, 64, 256, swf->frame_rate); st = vst; } - st->codec->width = width; - st->codec->height = height; if ((res = av_new_packet(pkt, out_len - colormapsize * colormapbpp)) < 0) goto bitmap_end; + if (!st->codec->width && !st->codec->height) { + st->codec->width = width; + st->codec->height = height; + } else { + ff_add_param_change(pkt, 0, 0, 0, width, height); + } pkt->pos = pos; pkt->stream_index = st->index; switch (bmp_fmt) { case 3: - st->codec->pix_fmt = AV_PIX_FMT_PAL8; + pix_fmt = AV_PIX_FMT_PAL8; for (i = 0; i < colormapsize; i++) if (alpha_bmp) colormap[i] = buf[3]<<24 | AV_RB24(buf + 4*i); else colormap[i] = 0xffU <<24 | AV_RB24(buf + 3*i); @@ -368,14 +373,20 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) memcpy(pal, colormap, AVPALETTE_SIZE); break; case 4: - st->codec->pix_fmt = AV_PIX_FMT_RGB555; + pix_fmt = AV_PIX_FMT_RGB555; break; case 5: - st->codec->pix_fmt = alpha_bmp ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB; + pix_fmt = alpha_bmp ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB; break; default: av_assert0(0); } + if (st->codec->pix_fmt != AV_PIX_FMT_NONE && st->codec->pix_fmt != pix_fmt) { + av_log(s, AV_LOG_ERROR, "pixel format change unsupported\n"); + res = AVERROR_PATCHWELCOME; + goto bitmap_end; + } + st->codec->pix_fmt = pix_fmt; if (linesize * height > pkt->size) { res = AVERROR_INVALIDDATA; diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c index a8fd9f91f0..5b7fd1fe5c 100644 --- a/libavformat/swfenc.c +++ b/libavformat/swfenc.c @@ -192,6 +192,10 @@ static int swf_write_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } if (enc->codec_id == AV_CODEC_ID_MP3) { + if (!enc->frame_size) { + av_log(s, AV_LOG_ERROR, "audio frame size not set\n"); + return -1; + } swf->audio_enc = enc; swf->audio_fifo= av_fifo_alloc(AUDIO_FIFO_SIZE); if (!swf->audio_fifo) @@ -457,7 +461,7 @@ static int swf_write_audio(AVFormatContext *s, } av_fifo_generic_write(swf->audio_fifo, buf, size, NULL); - swf->sound_samples += av_get_audio_frame_duration(enc, size); + swf->sound_samples += enc->frame_size; /* if audio only stream make sure we add swf frames */ if (!swf->video_enc) diff --git a/libavformat/thp.c b/libavformat/thp.c index 3717b8f12c..703a648a55 100644 --- a/libavformat/thp.c +++ b/libavformat/thp.c @@ -180,6 +180,8 @@ static int thp_read_packet(AVFormatContext *s, pkt->stream_index = thp->video_stream_index; } else { ret = av_get_packet(pb, pkt, thp->audiosize); + if (ret < 0) + return ret; if (ret != thp->audiosize) { av_free_packet(pkt); return AVERROR(EIO); diff --git a/libavformat/tta.c b/libavformat/tta.c index 445389ed95..2dce38f217 100644 --- a/libavformat/tta.c +++ b/libavformat/tta.c @@ -96,8 +96,10 @@ static int tta_read_header(AVFormatContext *s) for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); - av_add_index_entry(st, framepos, i * c->frame_size, size, 0, - AVINDEX_KEYFRAME); + int r; + if ((r = av_add_index_entry(st, framepos, i * c->frame_size, size, 0, + AVINDEX_KEYFRAME)) < 0) + return r; framepos += size; } avio_skip(s->pb, 4); // seektable crc @@ -135,6 +137,11 @@ static int tta_read_packet(AVFormatContext *s, AVPacket *pkt) if (c->currentframe >= c->totalframes) return AVERROR_EOF; + if (st->nb_index_entries < c->totalframes) { + av_log(s, AV_LOG_ERROR, "Index entry disappeared\n"); + return AVERROR_INVALIDDATA; + } + size = st->index_entries[c->currentframe].size; ret = av_get_packet(s->pb, pkt, size); diff --git a/libavformat/utils.c b/libavformat/utils.c index 5cbf7ca7af..360847fe68 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -432,10 +432,11 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) { - AVProbeData pd = { filename ? filename : "", NULL, -offset }; - unsigned char *buf = NULL; + AVProbeData pd = { filename ? filename : "" }; + uint8_t *buf = NULL; uint8_t *mime_type; int ret = 0, probe_size, buf_offset = 0; + int score = 0; if (!max_probe_size) { max_probe_size = PROBE_BUF_MAX; @@ -458,12 +459,9 @@ 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_RETRY : 0; void *buftmp; - if (probe_size < offset) { - continue; - } + score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; /* read probe data */ buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE); @@ -481,7 +479,10 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, score = 0; ret = 0; /* error was end of file, nothing read */ } - pd.buf_size = buf_offset += ret; + buf_offset += ret; + if (buf_offset < offset) + continue; + pd.buf_size = buf_offset - offset; pd.buf = &buf[offset]; memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); @@ -502,9 +503,9 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, } /* rewind. reuse probe buffer to avoid seeking */ - ret = ffio_rewind_with_probe_data(pb, &buf, pd.buf_size); + ret = ffio_rewind_with_probe_data(pb, &buf, buf_offset); - return ret; + return ret < 0 ? ret : score; } /* open input file and probe the format if necessary */ @@ -625,7 +626,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma goto fail; if (id3v2_extra_meta) { - if (!strcmp(s->iformat->name, "mp3")) { + if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac")) { if((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) goto fail; } else @@ -1163,12 +1164,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 } @@ -1455,6 +1458,9 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) st->skip_to_keyframe = 0; if (st->skip_to_keyframe) { av_free_packet(&cur_pkt); + if (got_packet) { + *pkt = cur_pkt; + } got_packet = 0; } } @@ -1526,7 +1532,8 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) } /* read packet from packet buffer, if there is data */ - if (!(next_pkt->pts == AV_NOPTS_VALUE && + st = s->streams[next_pkt->stream_index]; + if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL && next_pkt->dts != AV_NOPTS_VALUE && !eof)) { ret = read_from_packet_buffer(&s->packet_buffer, &s->packet_buffer_end, pkt); @@ -1765,7 +1772,10 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) { - return wrap_timestamp(s->streams[stream_index], read_timestamp(s, stream_index, ppos, pos_limit)); + int64_t ts = read_timestamp(s, stream_index, ppos, pos_limit); + if (stream_index >= 0) + ts = wrap_timestamp(s->streams[stream_index], ts); + return ts; } int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags) @@ -2247,16 +2257,21 @@ static void fill_all_stream_timings(AVFormatContext *ic) static void estimate_timings_from_bit_rate(AVFormatContext *ic) { int64_t filesize, duration; - int bit_rate, i; + int i; AVStream *st; /* if bit_rate is already set, we believe it */ if (ic->bit_rate <= 0) { - bit_rate = 0; + int 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; } @@ -2637,8 +2652,8 @@ static int get_std_framerate(int i){ * And there are "variable" fps files this needs to detect as well. */ static int tb_unreliable(AVCodecContext *c){ - if( c->time_base.den >= 101L*c->time_base.num - || c->time_base.den < 5L*c->time_base.num + if( c->time_base.den >= 101LL*c->time_base.num + || c->time_base.den < 5LL*c->time_base.num /* || c->codec_tag == AV_RL32("DIVX") || c->codec_tag == AV_RL32("XVID")*/ || c->codec_tag == AV_RL32("mp4v") @@ -2806,9 +2821,10 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) goto find_stream_info_err; } - read_size += pkt->size; - st = ic->streams[pkt->stream_index]; + if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) + read_size += pkt->size; + if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* check for non-increasing dts */ if (st->info->fps_last_dts != AV_NOPTS_VALUE && @@ -2970,6 +2986,10 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) int best_fps = 0; double best_error = 0.01; + if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| + st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || + st->info->codec_info_duration < 0) + continue; av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, st->info->codec_info_duration_fields*(int64_t)st->time_base.den, st->info->codec_info_duration*2*(int64_t)st->time_base.num, 60000); @@ -3177,13 +3197,13 @@ void ff_free_stream(AVFormatContext *s, AVStream *st){ if (st->attached_pic.data) av_free_packet(&st->attached_pic); 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); av_freep(&st->codec); av_freep(&st->priv_data); av_freep(&st->info); - av_freep(&st->probe_data.buf); av_freep(&s->streams[ --s->nb_streams ]); } diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c index 62215fc735..ceec81f51e 100644 --- a/libavformat/vocdec.c +++ b/libavformat/vocdec.c @@ -91,11 +91,11 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) if (sample_rate) dec->sample_rate = sample_rate; avpriv_set_pts_info(st, 64, 1, dec->sample_rate); + dec->channels = channels; + dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); } else avio_skip(pb, 1); - dec->channels = channels; tmp_codec = avio_r8(pb); - dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); voc->remaining_size -= 2; max_size -= 2; channels = 1; @@ -117,10 +117,10 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) if (!dec->sample_rate) { dec->sample_rate = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, dec->sample_rate); + dec->bits_per_coded_sample = avio_r8(pb); + dec->channels = avio_r8(pb); } else - avio_skip(pb, 4); - dec->bits_per_coded_sample = avio_r8(pb); - dec->channels = avio_r8(pb); + avio_skip(pb, 6); tmp_codec = avio_rl16(pb); avio_skip(pb, 4); voc->remaining_size -= 12; diff --git a/libavformat/vqf.c b/libavformat/vqf.c index f1e6aafd98..0d82ad1401 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -174,6 +174,10 @@ static int vqf_read_header(AVFormatContext *s) 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; if (st->codec->sample_rate <= 0) { av_log(s, AV_LOG_ERROR, "sample rate %d is invalid\n", st->codec->sample_rate); @@ -182,6 +186,13 @@ static int vqf_read_header(AVFormatContext *s) 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 : @@ -251,7 +262,7 @@ static int vqf_read_seek(AVFormatContext *s, { VqfContext *c = s->priv_data; AVStream *st; - int ret; + int64_t ret; int64_t pos; st = s->streams[stream_index]; diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 451187739f..b067d30d2f 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -62,6 +62,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) { @@ -74,7 +80,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; } @@ -356,7 +362,7 @@ static int wav_read_header(AVFormatContext *s) /* 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; } } @@ -368,8 +374,15 @@ break_loop: avio_seek(pb, data_ofs, SEEK_SET); - if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb)) - sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); + if (!sample_count || av_get_exact_bits_per_sample(st->codec->codec_id) > 0) + if ( st->codec->channels + && data_size + && av_get_bits_per_sample(st->codec->codec_id) + && wav->data_end <= avio_size(pb)) + sample_count = (data_size << 3) + / + (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); + if (sample_count) st->duration = sample_count; @@ -623,7 +636,7 @@ static int w64_read_header(AVFormatContext *s) uint32_t count, chunk_size, i; start = avio_tell(pb); - end = start + size; + end = start + FFALIGN(size, INT64_C(8)) - 24; count = avio_rl32(pb); for (i = 0; i < count; i++) { @@ -649,7 +662,7 @@ static int w64_read_header(AVFormatContext *s) avio_skip(pb, end - avio_tell(pb)); } else { av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid)); - avio_skip(pb, size - 24); + avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24); } } diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c index c996dad8a2..5a2e619246 100644 --- a/libavformat/westwood_vqa.c +++ b/libavformat/westwood_vqa.c @@ -106,7 +106,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 ee80719332..eb1dd3e0f1 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 + (int64_t)name_size > buf_end || name_size<0) { + if (name_size < 0) { + av_log(s, AV_LOG_ERROR, + "bad filename length, remaining directory entries ignored\n"); + break; + } + if (48 + (int64_t)name_size > buf_end - buf) { av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n"); break; } @@ -414,6 +419,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length) char description[1024]; unsigned int filesize; AVStream *st; + int ret; int64_t pos = avio_tell(pb); avio_get_str16le(pb, INT_MAX, mime, sizeof(mime)); @@ -430,13 +436,15 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length) if (!st) goto done; av_dict_set(&st->metadata, "title", description, 0); + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_MJPEG; - st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; - st->codec->extradata = av_mallocz(filesize); - if (!st->codec->extradata) + st->id = -1; + ret = av_get_packet(pb, &st->attached_pic, filesize); + if (ret < 0) goto done; - st->codec->extradata_size = filesize; - avio_read(pb, st->codec->extradata, filesize); + st->attached_pic.stream_index = st->index; + st->attached_pic.flags |= AV_PKT_FLAG_KEY; + st->disposition |= AV_DISPOSITION_ATTACHED_PIC; done: avio_seek(pb, pos + length, SEEK_SET); } diff --git a/libavformat/xmv.c b/libavformat/xmv.c index b447d6cd25..3a671972cf 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -49,6 +49,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. @@ -124,6 +126,15 @@ static int xmv_probe(AVProbeData *p) return 0; } +static int xmv_read_close(AVFormatContext *s) +{ + XMVDemuxContext *xmv = s->priv_data; + + av_freep(&xmv->audio); + + return 0; +} + static int xmv_read_header(AVFormatContext *s) { XMVDemuxContext *xmv = s->priv_data; @@ -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]; @@ -184,15 +198,10 @@ static int xmv_read_header(AVFormatContext *s) packet->bits_per_sample = avio_rl16(pb); packet->flags = avio_rl16(pb); - if (!packet->channels) { - av_log(s, AV_LOG_ERROR, "0 channels\n"); - return AVERROR(EINVAL); - } - 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); @@ -208,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; @@ -236,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) @@ -546,15 +569,6 @@ static int xmv_read_packet(AVFormatContext *s, return 0; } -static int xmv_read_close(AVFormatContext *s) -{ - XMVDemuxContext *xmv = s->priv_data; - - av_freep(&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 db7d9716ca..2606cdf9f0 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -201,8 +201,10 @@ static int xwma_read_header(AVFormatContext *s) /* 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, "bytes_per_sample is 0\n"); + 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; } diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c index 2b3d9f1f7a..f737a30fc8 100644 --- a/libavresample/audio_mix.c +++ b/libavresample/audio_mix.c @@ -195,23 +195,23 @@ static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len, while (len > 4) { v = *src++; - *dst0++ = v * m1; - *dst1++ = v * m0; + *dst0++ = v * m0; + *dst1++ = v * m1; v = *src++; - *dst0++ = v * m1; - *dst1++ = v * m0; + *dst0++ = v * m0; + *dst1++ = v * m1; v = *src++; - *dst0++ = v * m1; - *dst1++ = v * m0; + *dst0++ = v * m0; + *dst1++ = v * m1; v = *src++; - *dst0++ = v * m1; - *dst1++ = v * m0; + *dst0++ = v * m0; + *dst1++ = v * m1; len -= 4; } while (len > 0) { v = *src++; - *dst0++ = v * m1; - *dst1++ = v * m0; + *dst0++ = v * m0; + *dst1++ = v * m1; len--; } } @@ -401,10 +401,6 @@ AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr) av_free(matrix_dbl); } - ret = mix_function_init(am); - if (ret < 0) - goto error; - return am; error: @@ -544,8 +540,5 @@ int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride) return AVERROR(EINVAL); } - /* TODO: detect situations where we can just swap around pointers - instead of doing matrix multiplications with 0.0 and 1.0 */ - - return 0; + return mix_function_init(am); } diff --git a/libavresample/resample.c b/libavresample/resample.c index dc121fe56d..047572bcb9 100644 --- a/libavresample/resample.c +++ b/libavresample/resample.c @@ -46,6 +46,7 @@ struct ResampleContext { void (*resample_one)(struct ResampleContext *c, int no_filter, void *dst0, int dst_index, const void *src0, int src_size, int index, int frac); + int padding_size; }; @@ -211,6 +212,7 @@ ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr) goto error; c->ideal_dst_incr = c->dst_incr; + c->padding_size = (c->filter_length - 1) / 2; c->index = -phase_count * ((c->filter_length - 1) / 2); c->frac = 0; @@ -461,8 +463,10 @@ int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src) int avresample_get_delay(AVAudioResampleContext *avr) { + ResampleContext *c = avr->resample; + if (!avr->resample_needed || !avr->resample) return 0; - return avr->resample->buffer->nb_samples; + return FFMAX(c->buffer->nb_samples - c->padding_size, 0); } diff --git a/libavresample/utils.c b/libavresample/utils.c index 8f6583d6e8..31a2f37d53 100644 --- a/libavresample/utils.c +++ b/libavresample/utils.c @@ -117,7 +117,7 @@ int avresample_open(AVAudioResampleContext *avr) } if (avr->resample_needed) { avr->resample_out_buffer = ff_audio_data_alloc(avr->out_channels, - 0, avr->internal_sample_fmt, + 1024, avr->internal_sample_fmt, "resample_out_buffer"); if (!avr->resample_out_buffer) { ret = AVERROR(EINVAL); @@ -350,7 +350,8 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, resample_out = &output_buffer; else resample_out = avr->resample_out_buffer; - av_dlog(avr, "[resample] %s to %s\n", current_buffer->name, + av_dlog(avr, "[resample] %s to %s\n", + current_buffer ? current_buffer->name : "null", resample_out->name); ret = ff_audio_resample(avr->resample, resample_out, current_buffer); diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S index 6061e47a63..4d2a32e934 100644 --- a/libavutil/arm/asm.S +++ b/libavutil/arm/asm.S @@ -43,11 +43,17 @@ #elif HAVE_ARMV5TE .arch armv5te #endif +#if HAVE_AS_OBJECT_ARCH +ELF .object_arch armv4 +#endif #if HAVE_NEON .fpu neon +ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch +ELF .eabi_attribute 12, 0 @ suppress Tag_Advanced_SIMD_arch #elif HAVE_VFP .fpu vfp +ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch #endif .syntax unified @@ -212,6 +218,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/libavutil/arm/cpu.c b/libavutil/arm/cpu.c index 041afc985a..b4aabc375e 100644 --- a/libavutil/arm/cpu.c +++ b/libavutil/arm/cpu.c @@ -34,6 +34,8 @@ #include #include +#include +#include "libavutil/avstring.h" #define AT_HWCAP 16 @@ -66,13 +68,44 @@ static int get_hwcap(uint32_t *hwcap) return err; } +static int get_cpuinfo(uint32_t *hwcap) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + char buf[200]; + + if (!f) + return -1; + + *hwcap = 0; + while (fgets(buf, sizeof(buf), f)) { + if (av_strstart(buf, "Features", NULL)) { + if (strstr(buf, " edsp ")) + *hwcap |= HWCAP_EDSP; + if (strstr(buf, " tls ")) + *hwcap |= HWCAP_TLS; + if (strstr(buf, " thumbee ")) + *hwcap |= HWCAP_THUMBEE; + if (strstr(buf, " vfp ")) + *hwcap |= HWCAP_VFP; + if (strstr(buf, " vfpv3 ")) + *hwcap |= HWCAP_VFPv3; + if (strstr(buf, " neon ")) + *hwcap |= HWCAP_NEON; + break; + } + } + fclose(f); + return 0; +} + int ff_get_cpu_flags_arm(void) { int flags = CORE_CPU_FLAGS; uint32_t hwcap; if (get_hwcap(&hwcap) < 0) - return flags; + if (get_cpuinfo(&hwcap) < 0) + return flags; #define check_cap(cap, flag) do { \ if (hwcap & HWCAP_ ## cap) \ diff --git a/libavutil/cpu.c b/libavutil/cpu.c index a1d1547033..85bc2d6499 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -23,6 +23,24 @@ static int flags, checked; void av_force_cpu_flags(int arg){ + if ( (arg & ( AV_CPU_FLAG_3DNOW | + AV_CPU_FLAG_3DNOWEXT | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE2SLOW | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA4 )) + && !(arg & AV_CPU_FLAG_MMX)) { + av_log(NULL, AV_LOG_WARNING, "MMX implied by specified flags\n"); + arg |= AV_CPU_FLAG_MMX; + } + flags = arg; checked = arg != -1; } diff --git a/libavutil/intfloat_readwrite.c b/libavutil/intfloat_readwrite.c index 2998229e49..142331dac1 100644 --- a/libavutil/intfloat_readwrite.c +++ b/libavutil/intfloat_readwrite.c @@ -26,6 +26,7 @@ */ #include +#include "common.h" #include "mathematics.h" #include "intfloat_readwrite.h" @@ -88,7 +89,7 @@ AVExtFloat av_dbl2ext(double d){ ext.mantissa[i] = m>>(56-(i<<3)); } else if (f != 0.0) { ext.exponent[0] = 0x7f; ext.exponent[1] = 0xff; - if (f != INFINITY) + if (!isinf(f)) ext.mantissa[0] = ~0; } if (d < 0) diff --git a/libavutil/log.c b/libavutil/log.c index 700e89fa97..bdb4be0f91 100644 --- a/libavutil/log.c +++ b/libavutil/log.c @@ -101,6 +101,9 @@ static int use_color = -1; static void colored_fputs(int level, const char *str) { + if (!*str) + return; + if (use_color < 0) { #if HAVE_SETCONSOLETEXTATTRIBUTE CONSOLE_SCREEN_BUFFER_INFO con_info; @@ -178,7 +181,7 @@ static void format_line(void *ptr, int level, const char *fmt, va_list vl, if (parent && *parent) { snprintf(part[0], part_size, "[%s @ %p] ", (*parent)->item_name(parent), parent); - if(type) type[0] = get_category(((uint8_t *) ptr) + avc->parent_log_context_offset); + if(type) type[0] = get_category(parent); } } snprintf(part[1], part_size, "[%s @ %p] ", diff --git a/libavutil/lzo.c b/libavutil/lzo.c index c723257212..6a24a1dfc3 100644 --- a/libavutil/lzo.c +++ b/libavutil/lzo.c @@ -22,6 +22,7 @@ #include #include "avutil.h" +#include "avassert.h" #include "common.h" #include "intreadwrite.h" #include "lzo.h" @@ -65,8 +66,13 @@ static inline int get_len(LZOContext *c, int x, int mask) { int cnt = x & mask; if (!cnt) { - while (!(x = get_byte(c))) + while (!(x = get_byte(c))) { + if (cnt >= INT_MAX - 1000) { + c->error |= AV_LZO_ERROR; + break; + } cnt += 255; + } cnt += mask + x; } return cnt; @@ -80,6 +86,7 @@ static inline void copy(LZOContext *c, int cnt) { register const uint8_t *src = c->in; register uint8_t *dst = c->out; + av_assert0(cnt >= 0); if (cnt > c->in_end - src) { cnt = FFMAX(c->in_end - src, 0); c->error |= AV_LZO_INPUT_DEPLETED; @@ -103,16 +110,16 @@ static inline void copy(LZOContext *c, 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) { + av_assert0(cnt > 0); + if (dst - c->out_start < back) { c->error |= AV_LZO_INVALID_BACKPTR; return; } diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index f9cf87da80..2e0cf0cbd4 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -63,6 +63,9 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ av_assert2(b >=0); av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4); + if (c <= 0 || b < 0 || !((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4)) + return INT64_MIN; + if (rnd & AV_ROUND_PASS_MINMAX) { if (a == INT64_MIN || a == INT64_MAX) return a; diff --git a/libavutil/opt.c b/libavutil/opt.c index 61c76daa6e..d6c82ba3a9 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -249,7 +249,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { - int ret; + int ret = 0; void *dst, *target_obj; const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); if (!o || !target_obj) @@ -1291,8 +1291,10 @@ void av_opt_freep_ranges(AVOptionRanges **rangesp) for (i = 0; i < ranges->nb_ranges; i++) { AVOptionRange *range = ranges->range[i]; - av_freep(&range->str); - av_freep(&ranges->range[i]); + if (range) { + av_freep(&range->str); + av_freep(&ranges->range[i]); + } } av_freep(&ranges->range); av_freep(rangesp); diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c index 6f762df9b4..d25cc98fe7 100644 --- a/libavutil/samplefmt.c +++ b/libavutil/samplefmt.c @@ -135,6 +135,8 @@ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, /* auto-select alignment if not specified */ if (!align) { + if (nb_samples > INT_MAX - 31) + return AVERROR(EINVAL); align = 1; nb_samples = FFALIGN(nb_samples, 32); } diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index a3a5239159..9f8d7491e8 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -44,7 +44,7 @@ "cpuid \n\t" \ "xchg %%"REG_b", %%"REG_S \ : "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \ - : "0" (index)) + : "0" (index), "2"(0)) #define xgetbv(index, eax, edx) \ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index)) diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c index facfd2cdd9..78404e8ca3 100644 --- a/libpostproc/postprocess.c +++ b/libpostproc/postprocess.c @@ -975,7 +975,7 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], if(pict_type & PP_PICT_TYPE_QP2){ int i; - const int count= mbHeight * absQPStride; + const int count= FFMAX(mbHeight * absQPStride, mbWidth); for(i=0; i<(count>>2); i++){ ((uint32_t*)c->stdQPTable)[i] = (((const uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F; } @@ -1000,7 +1000,7 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], if((pict_type&7)!=3){ if (QPStride >= 0){ int i; - const int count= mbHeight * QPStride; + const int count= FFMAX(mbHeight * QPStride, mbWidth); for(i=0; i<(count>>2); i++){ ((uint32_t*)c->nonBQPTable)[i] = ((const uint32_t*)QP_store)[i] & 0x3F3F3F3F; } diff --git a/libswresample/Makefile b/libswresample/Makefile index 9d9f10c6c6..0b75bd0821 100644 --- a/libswresample/Makefile +++ b/libswresample/Makefile @@ -8,11 +8,11 @@ HEADERS = swresample.h \ OBJS = audioconvert.o \ dither.o \ - log2_tab.o \ rematrix.o \ resample.o \ swresample.o \ OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o +OBJS-$(CONFIG_SHARED) += log2_tab.o TESTPROGS = swresample diff --git a/libswresample/dither.c b/libswresample/dither.c index 79113f4c23..28cfbdd501 100644 --- a/libswresample/dither.c +++ b/libswresample/dither.c @@ -24,7 +24,7 @@ void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt) { double scale = 0; #define TMP_EXTRA 2 - double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double)); + double *tmp = av_malloc_array(len + TMP_EXTRA, sizeof(double)); int i; out_fmt = av_get_packed_sample_fmt(out_fmt); diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index 51658cee21..392eec838c 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -78,9 +78,6 @@ static int even(int64_t layout){ } static int clean_layout(SwrContext *s, int64_t layout){ - if((layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX) - return AV_CH_LAYOUT_STEREO; - if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) { char buf[128]; av_get_channel_layout_string(buf, sizeof(buf), -1, layout); @@ -118,13 +115,24 @@ av_cold static int auto_matrix(SwrContext *s) const int matrix_encoding = s->matrix_encoding; in_ch_layout = clean_layout(s, s->in_ch_layout); + out_ch_layout = clean_layout(s, s->out_ch_layout); + + if( out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX + && (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 + ) + out_ch_layout = AV_CH_LAYOUT_STEREO; + + if( in_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX + && (out_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 + ) + in_ch_layout = AV_CH_LAYOUT_STEREO; + if(!sane_layout(in_ch_layout)){ av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout); av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); return AVERROR(EINVAL); } - out_ch_layout = clean_layout(s, s->out_ch_layout); if(!sane_layout(out_ch_layout)){ av_get_channel_layout_string(buf, sizeof(buf), -1, s->out_ch_layout); av_log(s, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); diff --git a/libswresample/resample.c b/libswresample/resample.c index 6cd2b8cbcb..4ced9fafeb 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -95,7 +95,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap int filter_type, int kaiser_beta){ int ph, i; double x, y, w; - double *tab = av_malloc(tap_count * sizeof(*tab)); + double *tab = av_malloc_array(tap_count, sizeof(*tab)); const int center= (tap_count-1)/2; if (!tab) @@ -229,6 +229,11 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r av_assert0(0); } + if (filter_size/factor > INT32_MAX/256) { + av_log(NULL, AV_LOG_ERROR, "Filter length too large\n"); + goto error; + } + c->phase_shift = phase_shift; c->phase_mask = phase_count - 1; c->linear = linear; diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c index 15fcc83bf1..57aa51a53b 100644 --- a/libswresample/soxr_resample.c +++ b/libswresample/soxr_resample.c @@ -72,8 +72,12 @@ static int process( AudioData *src, int src_size, int *consumed){ size_t idone, odone; soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count)); - error = soxr_process((soxr_t)c, src->ch, (size_t)src_size, - &idone, dst->ch, (size_t)dst_size, &odone); + if (!error) + error = soxr_process((soxr_t)c, src->ch, (size_t)src_size, + &idone, dst->ch, (size_t)dst_size, &odone); + else + idone = 0; + *consumed = (int)idone; return error? -1 : odone; } diff --git a/libswresample/swresample.c b/libswresample/swresample.c index f01927f293..e93f707390 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -249,6 +249,16 @@ av_cold int swr_init(struct SwrContext *s){ return AVERROR(EINVAL); } + if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) { + av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout); + s->in_ch_layout = 0; + } + + if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) { + av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is invalid or unsupported.\n", s->out_ch_layout); + s->out_ch_layout = 0; + } + if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){ if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_S16P){ s->int_sample_fmt= AV_SAMPLE_FMT_S16P; @@ -826,7 +836,7 @@ int64_t swr_next_pts(struct SwrContext *s, int64_t pts){ if(s->min_compensation >= FLT_MAX) { return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate)); } else { - int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts; + int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate; double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate); if(fabs(fdelta) > s->min_compensation) { diff --git a/libswresample/x86/audio_convert.asm b/libswresample/x86/audio_convert.asm index ad46977c6f..4963959c54 100644 --- a/libswresample/x86/audio_convert.asm +++ b/libswresample/x86/audio_convert.asm @@ -195,7 +195,12 @@ cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len add lenq, 2*mmsize/(1<<%4) %endif jl .next +%if mmsize == 8 + emms + RET +%else REP_RET +%endif %endmacro %macro PACK_6CH 5-7 diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 2c9e3da86e..74b7940841 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -794,7 +794,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c, uint8_t *dst2[4]; uint8_t *rgb0_tmp = NULL; - if (!srcSlice || !dstStride || !dst || !srcSlice) { + if (!srcStride || !dstStride || !dst || !srcSlice) { av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n"); return 0; } diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 6a942d6799..55911b532a 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -37,7 +37,7 @@ #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long -#define YUVRGB_TABLE_HEADROOM 128 +#define YUVRGB_TABLE_HEADROOM 256 #define FAST_BGR2YV12 // use 7-bit instead of 15-bit coefficients diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index f35d1ba352..deabce2f5f 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -605,6 +605,9 @@ static rgbConvFn findRgbConvFn(SwsContext *c) } } + if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0) + return NULL; + return conv; } @@ -940,7 +943,7 @@ void ff_get_unscaled_swscale(SwsContext *c) c->swScale = ff_yuv2rgb_get_func_ptr(c); } - if (srcFormat == AV_PIX_FMT_YUV410P && + if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) && (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) { c->swScale = yvu9ToYv12Wrapper; diff --git a/libswscale/utils.c b/libswscale/utils.c index 89bf0da59b..80a079b05e 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -342,7 +342,7 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos, xDstInSrc = xInc - 0x10000; for (i = 0; i < dstW; i++) { - int xx = (xDstInSrc - ((filterSize - 2) << 16)) / (1 << 17); + int xx = (xDstInSrc - ((int64_t)(filterSize - 2) << 16)) / (1 << 17); int j; (*filterPos)[i] = xx; for (j = 0; j < filterSize; j++) { @@ -571,14 +571,25 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos, } if ((*filterPos)[i] + filterSize > srcW) { - int shift = (*filterPos)[i] + filterSize - srcW; - // move filter coefficients right to compensate for filterPos - for (j = filterSize - 2; j >= 0; j--) { - int right = FFMIN(j + shift, filterSize - 1); - filter[i * filterSize + right] += filter[i * filterSize + j]; - filter[i * filterSize + j] = 0; + int shift = (*filterPos)[i] + FFMIN(filterSize - srcW, 0); + int64_t acc = 0; + + for (j = filterSize - 1; j >= 0; j--) { + if ((*filterPos)[i] + j >= srcW) { + acc += filter[i * filterSize + j]; + filter[i * filterSize + j] = 0; + } } - (*filterPos)[i]= srcW - filterSize; + for (j = filterSize - 1; j >= 0; j--) { + if (j < shift) { + filter[i * filterSize + j] = 0; + } else { + filter[i * filterSize + j] = filter[i * filterSize + j - shift]; + } + } + + (*filterPos)[i]-= shift; + filter[i * filterSize + srcW - 1 - (*filterPos)[i]] += acc; } } @@ -1039,7 +1050,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, c->chrDstW = -((-dstW) >> c->chrDstHSubSample); c->chrDstH = -((-dstH) >> c->chrDstVSubSample); - FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); + FF_ALLOCZ_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); /* unscaled special cases */ if (unscaled && !usesHFilter && !usesVFilter && diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c index d802ab4227..242a7b2301 100644 --- a/libswscale/x86/rgb2rgb_template.c +++ b/libswscale/x86/rgb2rgb_template.c @@ -1864,6 +1864,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/swscale.c b/libswscale/x86/swscale.c index 02c454e08f..92579032c7 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -261,7 +261,8 @@ static void yuv2yuvX_sse3(const int16_t *filter, int filterSize, "jb 1b \n\t"\ :: "g" (filter), "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset) - : "%"REG_d, "%"REG_S, "%"REG_c + : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,) + "%"REG_d, "%"REG_S, "%"REG_c ); } #endif diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c index 62265db30f..2beace708c 100644 --- a/libswscale/x86/swscale_template.c +++ b/libswscale/x86/swscale_template.c @@ -321,7 +321,7 @@ static void RENAME(yuv2yuvX)(const int16_t *filter, int filterSize, MOVNTQ( q3, 24(dst, index, 4))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITEBGR32(dst, dstw, index, b, g, r, a, q0, q2, q3, t) REAL_WRITEBGR32(dst, dstw, index, b, g, r, a, q0, q2, q3, t) @@ -347,13 +347,13 @@ static void RENAME(yuv2rgb32_X_ar)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm3, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm2, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm3, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm2, %%mm6) YSCALEYUV2PACKEDX_END } else { YSCALEYUV2PACKEDX_ACCURATE YSCALEYUV2RGBX "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) YSCALEYUV2PACKEDX_END } } @@ -376,13 +376,13 @@ static void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) YSCALEYUV2PACKEDX_END } else { YSCALEYUV2PACKEDX YSCALEYUV2RGBX "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) YSCALEYUV2PACKEDX_END } } @@ -411,7 +411,7 @@ static void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter, MOVNTQ(%%mm1, 8(dst, index, 2))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITERGB16(dst, dstw, index) REAL_WRITERGB16(dst, dstw, index) @@ -435,7 +435,7 @@ static void RENAME(yuv2rgb565_X_ar)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4\n\t" "paddusb "RED_DITHER"(%0), %%mm5\n\t" #endif - WRITERGB16(%4, %5, %%REGa) + WRITERGB16(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -459,7 +459,7 @@ static void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4 \n\t" "paddusb "RED_DITHER"(%0), %%mm5 \n\t" #endif - WRITERGB16(%4, %5, %%REGa) + WRITERGB16(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -488,7 +488,7 @@ static void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter, MOVNTQ(%%mm1, 8(dst, index, 2))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITERGB15(dst, dstw, index) REAL_WRITERGB15(dst, dstw, index) @@ -512,7 +512,7 @@ static void RENAME(yuv2rgb555_X_ar)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4\n\t" "paddusb "RED_DITHER"(%0), %%mm5\n\t" #endif - WRITERGB15(%4, %5, %%REGa) + WRITERGB15(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -536,7 +536,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4 \n\t" "paddusb "RED_DITHER"(%0), %%mm5 \n\t" #endif - WRITERGB15(%4, %5, %%REGa) + WRITERGB15(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -590,7 +590,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter, "add $24, "#dst" \n\t"\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITEBGR24MMXEXT(dst, dstw, index) \ @@ -638,7 +638,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter, "add $24, "#dst" \n\t"\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #if COMPILE_TEMPLATE_MMXEXT @@ -665,7 +665,7 @@ static void RENAME(yuv2bgr24_X_ar)(SwsContext *c, const int16_t *lumFilter, "pxor %%mm7, %%mm7 \n\t" "lea (%%"REG_a", %%"REG_a", 2), %%"REG_c"\n\t" //FIXME optimize "add %4, %%"REG_c" \n\t" - WRITEBGR24(%%REGc, %5, %%REGa) + WRITEBGR24(%%REGc, "%5", %%REGa) :: "r" (&c->redDither), "m" (dummy), "m" (dummy), "m" (dummy), "r" (dest), "m" (dstW_reg), "m"(uv_off) @@ -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 } @@ -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), @@ -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), @@ -1178,7 +1174,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), @@ -1191,7 +1187,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), @@ -1207,7 +1203,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), @@ -1220,7 +1216,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), @@ -1246,7 +1242,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), @@ -1260,7 +1256,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), @@ -1291,7 +1287,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), @@ -1311,7 +1307,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), @@ -1342,7 +1338,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), @@ -1362,7 +1358,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), @@ -1423,7 +1419,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), @@ -1436,7 +1432,7 @@ static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0, "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED1b(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c index 53b69d0f73..48b54f3ece 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -266,16 +266,16 @@ YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1) PUTRGBA(dst_2, py_2, pa_2, 0, 24); LOADCHROMA(1); - PUTRGBA(dst_2, py_2, pa_1, 1, 24); - PUTRGBA(dst_1, py_1, pa_2, 1, 24); + PUTRGBA(dst_2, py_2, pa_2, 1, 24); + PUTRGBA(dst_1, py_1, pa_1, 1, 24); LOADCHROMA(2); PUTRGBA(dst_1, py_1, pa_1, 2, 24); PUTRGBA(dst_2, py_2, pa_2, 2, 24); LOADCHROMA(3); - PUTRGBA(dst_2, py_2, pa_1, 3, 24); - PUTRGBA(dst_1, py_1, pa_2, 3, 24); + PUTRGBA(dst_2, py_2, pa_2, 3, 24); + PUTRGBA(dst_1, py_1, pa_1, 3, 24); pa_1 += 8; \ pa_2 += 8; \ ENDYUV2RGBLINE(8, 0) @@ -284,8 +284,8 @@ ENDYUV2RGBLINE(8, 0) PUTRGBA(dst_2, py_2, pa_2, 0, 24); LOADCHROMA(1); - PUTRGBA(dst_2, py_2, pa_1, 1, 24); - PUTRGBA(dst_1, py_1, pa_2, 1, 24); + PUTRGBA(dst_2, py_2, pa_2, 1, 24); + PUTRGBA(dst_1, py_1, pa_1, 1, 24); pa_1 += 4; \ pa_2 += 4; \ ENDYUV2RGBLINE(8, 1) diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak index 2985a0e69a..a49490df22 100644 --- a/tests/fate/ac3.mak +++ b/tests/fate/ac3.mak @@ -52,14 +52,12 @@ fate-ac3-encode: CMD = enc_dec_pcm ac3 wav s16le $(REF) -c:a ac3 -b:a 128k fate-ac3-encode: CMP_SHIFT = -1024 fate-ac3-encode: CMP_TARGET = 399.62 fate-ac3-encode: SIZE_TOLERANCE = 488 -fate-ac3-encode: FUZZ = 4 FATE_EAC3-$(call ENCDEC, EAC3, EAC3) += fate-eac3-encode fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(REF) -c:a eac3 -b:a 128k fate-eac3-encode: CMP_SHIFT = -1024 fate-eac3-encode: CMP_TARGET = 514.02 fate-eac3-encode: SIZE_TOLERANCE = 488 -fate-eac3-encode: FUZZ = 3 fate-ac3-encode fate-eac3-encode: CMP = stddev fate-ac3-encode fate-eac3-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak index 20d563828f..d2a390404b 100644 --- a/tests/fate/fft.mak +++ b/tests/fate/fft.mak @@ -1,8 +1,8 @@ define DEF_FFT -FATE_FFT += fate-fft-$(1) fate-ifft-$(1) \ - fate-mdct-$(1) fate-imdct-$(1) \ - fate-rdft-$(1) fate-irdft-$(1) \ - fate-dct1d-$(1) fate-idct1d-$(1) +FATE_FFT-$(CONFIG_DCT) += fate-dct1d-$(1) fate-idct1d-$(1) +FATE_FFT-$(CONFIG_FFT) += fate-fft-$(1) fate-ifft-$(1) +FATE_FFT-$(CONFIG_MDCT) += fate-mdct-$(1) fate-imdct-$(1) +FATE_FFT-$(CONFIG_RDFT) += fate-rdft-$(1) fate-irdft-$(1) fate-fft-$(N): ARGS = -n$(1) fate-ifft-$(N): ARGS = -n$(1) -i @@ -16,14 +16,14 @@ endef $(foreach N, 4 5 6 7 8 9 10 11 12, $(eval $(call DEF_FFT,$(N)))) -fate-fft-test: $(FATE_FFT) -$(FATE_FFT): libavcodec/fft-test$(EXESUF) -$(FATE_FFT): CMD = run libavcodec/fft-test $(CPUFLAGS:%=-c%) $(ARGS) -$(FATE_FFT): REF = /dev/null +fate-fft-float: $(FATE_FFT-yes) +$(FATE_FFT-yes): libavcodec/fft-test$(EXESUF) +$(FATE_FFT-yes): CMD = run libavcodec/fft-test $(CPUFLAGS:%=-c%) $(ARGS) +$(FATE_FFT-yes): REF = /dev/null define DEF_FFT_FIXED -FATE_FFT_FIXED += fate-fft-fixed-$(1) fate-ifft-fixed-$(1) \ - fate-mdct-fixed-$(1) fate-imdct-fixed-$(1) +FATE_FFT_FIXED-$(CONFIG_FFT) += fate-fft-fixed-$(1) fate-ifft-fixed-$(1) +FATE_FFT_FIXED-$(CONFIG_MDCT) += fate-mdct-fixed-$(1) fate-imdct-fixed-$(1) fate-fft-fixed-$(1): ARGS = -n$(1) fate-ifft-fixed-$(1): ARGS = -n$(1) -i @@ -33,10 +33,10 @@ endef $(foreach N, 4 5 6 7 8 9 10 11 12, $(eval $(call DEF_FFT_FIXED,$(N)))) -fate-fft-fixed-test: $(FATE_FFT_FIXED) -$(FATE_FFT_FIXED): libavcodec/fft-fixed-test$(EXESUF) -$(FATE_FFT_FIXED): CMD = run libavcodec/fft-fixed-test $(CPUFLAGS:%=-c%) $(ARGS) -$(FATE_FFT_FIXED): REF = /dev/null +fate-fft-fixed: $(FATE_FFT_FIXED-yes) +$(FATE_FFT_FIXED-yes): libavcodec/fft-fixed-test$(EXESUF) +$(FATE_FFT_FIXED-yes): CMD = run libavcodec/fft-fixed-test $(CPUFLAGS:%=-c%) $(ARGS) +$(FATE_FFT_FIXED-yes): REF = /dev/null -FATE-$(call ALLYES, AVCODEC FFT) += $(FATE_FFT) $(FATE_FFT_FIXED) -fate-fft: $(FATE_FFT) $(FATE_FFT_FIXED) +FATE-$(CONFIG_AVCODEC) += $(FATE_FFT-yes) $(FATE_FFT_FIXED-yes) +fate-fft: $(FATE_FFT-yes) $(FATE_FFT_FIXED-yes) diff --git a/tests/ref/fate/filter-delogo b/tests/ref/fate/filter-delogo index e0f24cd8ce..bc58777304 100644 --- a/tests/ref/fate/filter-delogo +++ b/tests/ref/fate/filter-delogo @@ -8,13 +8,13 @@ 0, 6, 6, 1, 126720, 0x94a0f126 0, 7, 7, 1, 126720, 0x0250f106 0, 8, 8, 1, 126720, 0xcf6ab4bc -0, 9, 9, 1, 126720, 0x44aeb57c -0, 10, 10, 1, 126720, 0x33b0b5bc -0, 11, 11, 1, 126720, 0xc4bab591 +0, 9, 9, 1, 126720, 0x429eb57c +0, 10, 10, 1, 126720, 0x3bf0b5bc +0, 11, 11, 1, 126720, 0xcaedb591 0, 12, 12, 1, 126720, 0xa492b5ec -0, 13, 13, 1, 126720, 0x1459b85c -0, 14, 14, 1, 126720, 0x806fb8dc -0, 15, 15, 1, 126720, 0xd241b871 +0, 13, 13, 1, 126720, 0x2431b85c +0, 14, 14, 1, 126720, 0x8283b8dc +0, 15, 15, 1, 126720, 0xd71bb871 0, 16, 16, 1, 126720, 0x698eb5cc 0, 17, 17, 1, 126720, 0x4719aa98 0, 18, 18, 1, 126720, 0x9ca1962c @@ -28,83 +28,83 @@ 0, 26, 26, 1, 126720, 0x7af2ea86 0, 27, 27, 1, 126720, 0x40d4b4eb 0, 28, 28, 1, 126720, 0x49d00307 -0, 29, 29, 1, 126720, 0x44c8848e -0, 30, 30, 1, 126720, 0xc6990101 -0, 31, 31, 1, 126720, 0x2e01b963 +0, 29, 29, 1, 126720, 0x0654849c +0, 30, 30, 1, 126720, 0xe46d0107 +0, 31, 31, 1, 126720, 0xa483b963 0, 32, 32, 1, 126720, 0xd0e903f0 -0, 33, 33, 1, 126720, 0x3457d592 -0, 34, 34, 1, 126720, 0x4f1ddb3c -0, 35, 35, 1, 126720, 0x3980ace5 +0, 33, 33, 1, 126720, 0x964ed592 +0, 34, 34, 1, 126720, 0x23fbdb3c +0, 35, 35, 1, 126720, 0x59fdace5 0, 36, 36, 1, 126720, 0xb1e37954 -0, 37, 37, 1, 126720, 0x619fc554 -0, 38, 38, 1, 126720, 0x945fb39e -0, 39, 39, 1, 126720, 0xb1d5e0ce +0, 37, 37, 1, 126720, 0x8ed9c554 +0, 38, 38, 1, 126720, 0xe3c4b39f +0, 39, 39, 1, 126720, 0xfd17e0ce 0, 40, 40, 1, 126720, 0xf26e1dcc -0, 41, 41, 1, 126720, 0x04d5783e -0, 42, 42, 1, 126720, 0xbaa0479e -0, 43, 43, 1, 126720, 0x20d88b01 +0, 41, 41, 1, 126720, 0x13cc783c +0, 42, 42, 1, 126720, 0x47ad47a1 +0, 43, 43, 1, 126720, 0x427c8b0d 0, 44, 44, 1, 126720, 0x59d99901 -0, 45, 45, 1, 126720, 0x1c6e09f6 -0, 46, 46, 1, 126720, 0xeec50fc5 -0, 47, 47, 1, 126720, 0xb3a92827 -0, 48, 48, 1, 126720, 0xf62dd2b6 -0, 49, 49, 1, 126720, 0x75b1e619 -0, 50, 50, 1, 126720, 0x6bbce2c0 -0, 51, 51, 1, 126720, 0xd93e023c -0, 52, 52, 1, 126720, 0xbbe8e7c2 -0, 53, 53, 1, 126720, 0x2272ec17 -0, 54, 54, 1, 126720, 0xf5e4ee6e -0, 55, 55, 1, 126720, 0x751d2607 -0, 56, 56, 1, 126720, 0x44c499c9 -0, 57, 57, 1, 126720, 0xddccd842 -0, 58, 58, 1, 126720, 0x508dd214 -0, 59, 59, 1, 126720, 0x8eb10272 -0, 60, 60, 1, 126720, 0x7224b1c6 -0, 61, 61, 1, 126720, 0x50ff456c -0, 62, 62, 1, 126720, 0xa81e2731 -0, 63, 63, 1, 126720, 0x7e50456d -0, 64, 64, 1, 126720, 0x44802978 -0, 65, 65, 1, 126720, 0x86e88743 -0, 66, 66, 1, 126720, 0x0b1087d6 -0, 67, 67, 1, 126720, 0xb0227d21 -0, 68, 68, 1, 126720, 0x29d10bd2 -0, 69, 69, 1, 126720, 0x04b43afa -0, 70, 70, 1, 126720, 0xb48e9698 -0, 71, 71, 1, 126720, 0x75d760fb -0, 72, 72, 1, 126720, 0xa2ab1fdb -0, 73, 73, 1, 126720, 0xec30a5ee -0, 74, 74, 1, 126720, 0xbdab7c8c -0, 75, 75, 1, 126720, 0xac5c3f2c -0, 76, 76, 1, 126720, 0xce6350be -0, 77, 77, 1, 126720, 0xb109657a -0, 78, 78, 1, 126720, 0x723865a4 -0, 79, 79, 1, 126720, 0xa9869124 -0, 80, 80, 1, 126720, 0xc41af558 -0, 81, 81, 1, 126720, 0xcbe6a402 -0, 82, 82, 1, 126720, 0xb6735ecb -0, 83, 83, 1, 126720, 0xba3059f2 -0, 84, 84, 1, 126720, 0xe7d63b8d -0, 85, 85, 1, 126720, 0x8f115906 -0, 86, 86, 1, 126720, 0xaf6a8dcb -0, 87, 87, 1, 126720, 0xb73e846e -0, 88, 88, 1, 126720, 0xedd6380f -0, 89, 89, 1, 126720, 0xd9026acf -0, 90, 90, 1, 126720, 0xa03a650b -0, 91, 91, 1, 126720, 0x262765bc -0, 92, 92, 1, 126720, 0xaaa9ded1 -0, 93, 93, 1, 126720, 0xe4f42665 -0, 94, 94, 1, 126720, 0x78daf760 -0, 95, 95, 1, 126720, 0x3b0c6ef8 -0, 96, 96, 1, 126720, 0xb745df80 -0, 97, 97, 1, 126720, 0x08e57b90 -0, 98, 98, 1, 126720, 0x6f883ab0 -0, 99, 99, 1, 126720, 0x934b4dd5 -0, 100, 100, 1, 126720, 0x762f108f -0, 101, 101, 1, 126720, 0x91ee0f2b -0, 102, 102, 1, 126720, 0x9af6e5e8 -0, 103, 103, 1, 126720, 0xdcd95e0a -0, 104, 104, 1, 126720, 0x22c33a6e -0, 105, 105, 1, 126720, 0x21c1b7f4 -0, 106, 106, 1, 126720, 0x0a66a1ed -0, 107, 107, 1, 126720, 0x53fea81b -0, 108, 108, 1, 126720, 0x597f5567 +0, 45, 45, 1, 126720, 0xc40707da +0, 46, 46, 1, 126720, 0xcd060dce +0, 47, 47, 1, 126720, 0xed4024f6 +0, 48, 48, 1, 126720, 0x7decd2b4 +0, 49, 49, 1, 126720, 0xd1d2e730 +0, 50, 50, 1, 126720, 0x77cee457 +0, 51, 51, 1, 126720, 0xe78d02c0 +0, 52, 52, 1, 126720, 0xad0beb29 +0, 53, 53, 1, 126720, 0xc414eea2 +0, 54, 54, 1, 126720, 0x6a15f17d +0, 55, 55, 1, 126720, 0x516027f6 +0, 56, 56, 1, 126720, 0x4eda9dce +0, 57, 57, 1, 126720, 0x7d9bdba3 +0, 58, 58, 1, 126720, 0x7aa3d5c0 +0, 59, 59, 1, 126720, 0x7c7a04f9 +0, 60, 60, 1, 126720, 0x3e8fb6cc +0, 61, 61, 1, 126720, 0xd5474916 +0, 62, 62, 1, 126720, 0xf3f62bab +0, 63, 63, 1, 126720, 0x2f054987 +0, 64, 64, 1, 126720, 0x974c2e81 +0, 65, 65, 1, 126720, 0xe7e28a97 +0, 66, 66, 1, 126720, 0x45e38b41 +0, 67, 67, 1, 126720, 0x169c7f19 +0, 68, 68, 1, 126720, 0x91d90ee8 +0, 69, 69, 1, 126720, 0xdd653e24 +0, 70, 70, 1, 126720, 0x0da598c4 +0, 71, 71, 1, 126720, 0x687e62cc +0, 72, 72, 1, 126720, 0x7631232d +0, 73, 73, 1, 126720, 0xbd1ea826 +0, 74, 74, 1, 126720, 0xb55f7f4b +0, 75, 75, 1, 126720, 0x923f3fc9 +0, 76, 76, 1, 126720, 0x15515301 +0, 77, 77, 1, 126720, 0x9ee066e5 +0, 78, 78, 1, 126720, 0x7c21664b +0, 79, 79, 1, 126720, 0x36849100 +0, 80, 80, 1, 126720, 0x08b1f61a +0, 81, 81, 1, 126720, 0x5bfca6e2 +0, 82, 82, 1, 126720, 0x929f60e3 +0, 83, 83, 1, 126720, 0xa2b55c29 +0, 84, 84, 1, 126720, 0x68bd3ff3 +0, 85, 85, 1, 126720, 0x30db5b29 +0, 86, 86, 1, 126720, 0x00578f9b +0, 87, 87, 1, 126720, 0x18368642 +0, 88, 88, 1, 126720, 0xbcb83a80 +0, 89, 89, 1, 126720, 0x90f36b72 +0, 90, 90, 1, 126720, 0x85e46522 +0, 91, 91, 1, 126720, 0x2429660a +0, 92, 92, 1, 126720, 0xf283dfe2 +0, 93, 93, 1, 126720, 0x896b27dc +0, 94, 94, 1, 126720, 0x5af4f961 +0, 95, 95, 1, 126720, 0x31897085 +0, 96, 96, 1, 126720, 0x441ce33e +0, 97, 97, 1, 126720, 0x903f8009 +0, 98, 98, 1, 126720, 0xbdf33dba +0, 99, 99, 1, 126720, 0x8a364f36 +0, 100, 100, 1, 126720, 0xda5513f6 +0, 101, 101, 1, 126720, 0xd60012b3 +0, 102, 102, 1, 126720, 0x67bce7be +0, 103, 103, 1, 126720, 0x697e6174 +0, 104, 104, 1, 126720, 0xbe3e3e90 +0, 105, 105, 1, 126720, 0xf3e4bba6 +0, 106, 106, 1, 126720, 0x8124a679 +0, 107, 107, 1, 126720, 0x58d1acde +0, 108, 108, 1, 126720, 0xd8a15ba3 diff --git a/tests/ref/fate/fraps-v1 b/tests/ref/fate/fraps-v1 index 64392c33b4..29c7e37df3 100644 --- a/tests/ref/fate/fraps-v1 +++ b/tests/ref/fate/fraps-v1 @@ -1,2 +1,2 @@ #tb 0: 1/25 -0, 0, 0, 1, 230400, 0x6bc891ff +0, 0, 0, 1, 230400, 0x23c29d17 diff --git a/tests/ref/fate/nuv-rtjpeg b/tests/ref/fate/nuv-rtjpeg index 8838fbb646..96ead33cbd 100644 --- a/tests/ref/fate/nuv-rtjpeg +++ b/tests/ref/fate/nuv-rtjpeg @@ -7,4 +7,3 @@ 0, 9, 9, 1, 460800, 0x4e091ee2 0, 10, 10, 1, 460800, 0x2ea88828 0, 11, 11, 1, 460800, 0x4b7f4df0 -0, 12, 12, 1, 460800, 0xa57f20d0 diff --git a/tests/ref/fate/rv30 b/tests/ref/fate/rv30 index df002d948b..70db647985 100644 --- a/tests/ref/fate/rv30 +++ b/tests/ref/fate/rv30 @@ -8,13 +8,13 @@ 0, 6, 6, 1, 126720, 0x5e6ff4d7 0, 7, 7, 1, 126720, 0xcc10f4b7 0, 8, 8, 1, 126720, 0x763ab817 -0, 9, 9, 1, 126720, 0xeb6fb8d7 -0, 10, 10, 1, 126720, 0xda71b917 -0, 11, 11, 1, 126720, 0x0967b8f7 +0, 9, 9, 1, 126720, 0xe95fb8d7 +0, 10, 10, 1, 126720, 0xe2b1b917 +0, 11, 11, 1, 126720, 0x11abb8f7 0, 12, 12, 1, 126720, 0x4b62b947 -0, 13, 13, 1, 126720, 0xbb1abbb7 -0, 14, 14, 1, 126720, 0x273fbc37 -0, 15, 15, 1, 126720, 0x16eebbd7 +0, 13, 13, 1, 126720, 0xcaf2bbb7 +0, 14, 14, 1, 126720, 0x2953bc37 +0, 15, 15, 1, 126720, 0x1dd9bbd7 0, 16, 16, 1, 126720, 0x105eb927 0, 17, 17, 1, 126720, 0x7fa3ae27 0, 18, 18, 1, 126720, 0x722e99f7 @@ -28,83 +28,83 @@ 0, 26, 26, 1, 126720, 0x6ddaef32 0, 27, 27, 1, 126720, 0xde1bb900 0, 28, 28, 1, 126720, 0xac6c071b -0, 29, 29, 1, 126720, 0x04e7897c -0, 30, 30, 1, 126720, 0x5eee050f -0, 31, 31, 1, 126720, 0xe675be59 +0, 29, 29, 1, 126720, 0x4a9f897c +0, 30, 30, 1, 126720, 0xd8fa050f +0, 31, 31, 1, 126720, 0x5d06be59 0, 32, 32, 1, 126720, 0xdc3e0837 -0, 33, 33, 1, 126720, 0x68cfda2b -0, 34, 34, 1, 126720, 0xe572dfc9 -0, 35, 35, 1, 126720, 0x582fb176 +0, 33, 33, 1, 126720, 0xcac6da2b +0, 34, 34, 1, 126720, 0x6672dfc9 +0, 35, 35, 1, 126720, 0x7491b176 0, 36, 36, 1, 126720, 0xa9477df0 -0, 37, 37, 1, 126720, 0xbc3cc34f -0, 38, 38, 1, 126720, 0xcf8cb0e2 -0, 39, 39, 1, 126720, 0xcff1db35 +0, 37, 37, 1, 126720, 0xe976c34f +0, 38, 38, 1, 126720, 0xdb7ab0e2 +0, 39, 39, 1, 126720, 0x1b42db35 0, 40, 40, 1, 126720, 0xc6e10f9f -0, 41, 41, 1, 126720, 0x75ae61b6 -0, 42, 42, 1, 126720, 0x12af3119 -0, 43, 43, 1, 126720, 0x85597543 +0, 41, 41, 1, 126720, 0x169d61b6 +0, 42, 42, 1, 126720, 0xc7623119 +0, 43, 43, 1, 126720, 0x5b9b7543 0, 44, 44, 1, 126720, 0x68c27aca -0, 45, 45, 1, 126720, 0x554fe3e4 -0, 46, 46, 1, 126720, 0x72ecea95 -0, 47, 47, 1, 126720, 0xf4d003d1 -0, 48, 48, 1, 126720, 0x9bf6a605 -0, 49, 49, 1, 126720, 0x5d00b5fe -0, 50, 50, 1, 126720, 0x93f7b040 -0, 51, 51, 1, 126720, 0x0d6ad154 -0, 52, 52, 1, 126720, 0x4be8b4ea -0, 53, 53, 1, 126720, 0xe39bba0d -0, 54, 54, 1, 126720, 0x9c21bad8 -0, 55, 55, 1, 126720, 0xa567f25b -0, 56, 56, 1, 126720, 0x7a82663a -0, 57, 57, 1, 126720, 0x72f2a47d -0, 58, 58, 1, 126720, 0x4f639ebe -0, 59, 59, 1, 126720, 0xab0fce83 -0, 60, 60, 1, 126720, 0x6cf87d39 -0, 61, 61, 1, 126720, 0x534a10cc -0, 62, 62, 1, 126720, 0x6bbcf44c -0, 63, 63, 1, 126720, 0xfdca11d3 -0, 64, 64, 1, 126720, 0x7e58f5a6 -0, 65, 65, 1, 126720, 0x5fd753d8 -0, 66, 66, 1, 126720, 0x0c735615 -0, 67, 67, 1, 126720, 0x2a034ebf -0, 68, 68, 1, 126720, 0xeaf3dd0b -0, 69, 69, 1, 126720, 0x0eaf0c1b -0, 70, 70, 1, 126720, 0xce5e6794 -0, 71, 71, 1, 126720, 0xf27c31c3 -0, 72, 72, 1, 126720, 0xb64af168 -0, 73, 73, 1, 126720, 0x14cf7974 -0, 74, 74, 1, 126720, 0x1c2a513d -0, 75, 75, 1, 126720, 0xa3f515ab -0, 76, 76, 1, 126720, 0xcfd62765 -0, 77, 77, 1, 126720, 0xbc513f2a -0, 78, 78, 1, 126720, 0xbc303fae -0, 79, 79, 1, 126720, 0x2f8f69b9 -0, 80, 80, 1, 126720, 0x0a22cc69 -0, 81, 81, 1, 126720, 0xd9f67585 -0, 82, 82, 1, 126720, 0x20403001 -0, 83, 83, 1, 126720, 0xf92b2a25 -0, 84, 84, 1, 126720, 0x3c170aad -0, 85, 85, 1, 126720, 0x3378251f -0, 86, 86, 1, 126720, 0xb3ed5911 -0, 87, 87, 1, 126720, 0x35d24ef8 -0, 88, 88, 1, 126720, 0x8da30275 -0, 89, 89, 1, 126720, 0xc15a3577 -0, 90, 90, 1, 126720, 0xf2942f53 -0, 91, 91, 1, 126720, 0x44d8304a -0, 92, 92, 1, 126720, 0xd688a932 -0, 93, 93, 1, 126720, 0x0a24f256 -0, 94, 94, 1, 126720, 0xfab9c45d -0, 95, 95, 1, 126720, 0x10e939ce -0, 96, 96, 1, 126720, 0x97fcaa3a -0, 97, 97, 1, 126720, 0x45464610 -0, 98, 98, 1, 126720, 0xfe2e057d -0, 99, 99, 1, 126720, 0x0b6718ae -0, 100, 100, 1, 126720, 0x5284da7b -0, 101, 101, 1, 126720, 0x23efdc35 -0, 102, 102, 1, 126720, 0xc387b2b3 -0, 103, 103, 1, 126720, 0xc9e92bf1 -0, 104, 104, 1, 126720, 0xfbf20a01 -0, 105, 105, 1, 126720, 0x4d888b2e -0, 106, 106, 1, 126720, 0xdd0d74df -0, 107, 107, 1, 126720, 0x49d07aa4 -0, 108, 108, 1, 126720, 0x08382b8e +0, 45, 45, 1, 126720, 0xa0e4e1c9 +0, 46, 46, 1, 126720, 0xbbdae87e +0, 47, 47, 1, 126720, 0xe67e00a1 +0, 48, 48, 1, 126720, 0x648ea605 +0, 49, 49, 1, 126720, 0x5becb718 +0, 50, 50, 1, 126720, 0xb79ab1da +0, 51, 51, 1, 126720, 0x0d52d1dc +0, 52, 52, 1, 126720, 0x1277b853 +0, 53, 53, 1, 126720, 0xc57cbc83 +0, 54, 54, 1, 126720, 0x2126bdc3 +0, 55, 55, 1, 126720, 0x4c1ef41f +0, 56, 56, 1, 126720, 0x185f6a2c +0, 57, 57, 1, 126720, 0xb2b5a7d3 +0, 58, 58, 1, 126720, 0x32d7a26d +0, 59, 59, 1, 126720, 0x0bffd118 +0, 60, 60, 1, 126720, 0x2eed823a +0, 61, 61, 1, 126720, 0xc4c0147c +0, 62, 62, 1, 126720, 0x1f8bf8ac +0, 63, 63, 1, 126720, 0xfcb715e8 +0, 64, 64, 1, 126720, 0xc3e9fa9c +0, 65, 65, 1, 126720, 0x9ad8572c +0, 66, 66, 1, 126720, 0x2800596d +0, 67, 67, 1, 126720, 0x3caa5094 +0, 68, 68, 1, 126720, 0x6162e000 +0, 69, 69, 1, 126720, 0x18200f2c +0, 70, 70, 1, 126720, 0x649e699f +0, 71, 71, 1, 126720, 0x5f513367 +0, 72, 72, 1, 126720, 0x71fbf4a8 +0, 73, 73, 1, 126720, 0x5bff7b97 +0, 74, 74, 1, 126720, 0xbad453d4 +0, 75, 75, 1, 126720, 0x56e6161d +0, 76, 76, 1, 126720, 0x524f2980 +0, 77, 77, 1, 126720, 0x0589405a +0, 78, 78, 1, 126720, 0x5c264043 +0, 79, 79, 1, 126720, 0x2394696f +0, 80, 80, 1, 126720, 0x1aa0cd15 +0, 81, 81, 1, 126720, 0xd6ec7840 +0, 82, 82, 1, 126720, 0xde5531f0 +0, 83, 83, 1, 126720, 0x03a42c3a +0, 84, 84, 1, 126720, 0xbdee0efb +0, 85, 85, 1, 126720, 0xa6012736 +0, 86, 86, 1, 126720, 0x448f5ae6 +0, 87, 87, 1, 126720, 0x8a2550c3 +0, 88, 88, 1, 126720, 0x143104e7 +0, 89, 89, 1, 126720, 0x75db363d +0, 90, 90, 1, 126720, 0x906d2f9d +0, 91, 91, 1, 126720, 0xfc7b30ab +0, 92, 92, 1, 126720, 0xd3edaa62 +0, 93, 93, 1, 126720, 0x6267f3fc +0, 94, 94, 1, 126720, 0x87b6c67f +0, 95, 95, 1, 126720, 0x84da3b79 +0, 96, 96, 1, 126720, 0x72fbae15 +0, 97, 97, 1, 126720, 0xb8474a80 +0, 98, 98, 1, 126720, 0xbeae088b +0, 99, 99, 1, 126720, 0x538b1a14 +0, 100, 100, 1, 126720, 0x07bbddcd +0, 101, 101, 1, 126720, 0x807ddf8f +0, 102, 102, 1, 126720, 0x325bb46d +0, 103, 103, 1, 126720, 0xd80c2f2a +0, 104, 104, 1, 126720, 0xfc1b0dec +0, 105, 105, 1, 126720, 0x46068ebc +0, 106, 106, 1, 126720, 0xcd987941 +0, 107, 107, 1, 126720, 0x52f37f2e +0, 108, 108, 1, 126720, 0xc96931a2 diff --git a/tests/ref/fate/xxan-wc4 b/tests/ref/fate/xxan-wc4 index 34857bfd26..88dcc98ac5 100644 --- a/tests/ref/fate/xxan-wc4 +++ b/tests/ref/fate/xxan-wc4 @@ -1,22 +1,22 @@ #tb 0: 1/15 -0, 0, 0, 1, 79360, 0x3b0a7d1b -0, 1, 1, 1, 79360, 0x740842c3 -0, 2, 2, 1, 79360, 0x85160167 -0, 3, 3, 1, 79360, 0xaf510e92 -0, 4, 4, 1, 79360, 0x8e290bec -0, 5, 5, 1, 79360, 0x51e981b0 -0, 6, 6, 1, 79360, 0x16e52c60 -0, 7, 7, 1, 79360, 0x66e1e60a -0, 8, 8, 1, 79360, 0x40fa58f6 -0, 9, 9, 1, 79360, 0x00388edd -0, 10, 10, 1, 79360, 0xc74f95bf -0, 11, 11, 1, 79360, 0xf446a3fd -0, 12, 12, 1, 79360, 0x27b5eb60 -0, 13, 13, 1, 79360, 0xea9266a2 -0, 14, 14, 1, 79360, 0x7b6a7907 -0, 15, 15, 1, 79360, 0x2be7d946 -0, 16, 16, 1, 79360, 0x61881ee4 -0, 17, 17, 1, 79360, 0x9214bd4f -0, 18, 18, 1, 79360, 0xeb294afe -0, 19, 19, 1, 79360, 0xc861ad55 -0, 20, 20, 1, 79360, 0x3d3b6220 +0, 0, 0, 1, 79360, 0x8537821b +0, 1, 1, 1, 79360, 0x110c4343 +0, 2, 2, 1, 79360, 0xa85105bb +0, 3, 3, 1, 79360, 0x87431836 +0, 4, 4, 1, 79360, 0x5c701720 +0, 5, 5, 1, 79360, 0x20308ce4 +0, 6, 6, 1, 79360, 0xe51d3794 +0, 7, 7, 1, 79360, 0x80e6f1e0 +0, 8, 8, 1, 79360, 0x5aff64cc +0, 9, 9, 1, 79360, 0x1a3d9ab3 +0, 10, 10, 1, 79360, 0xe154a195 +0, 11, 11, 1, 79360, 0x608dafdc +0, 12, 12, 1, 79360, 0x93edf73f +0, 13, 13, 1, 79360, 0x56d97281 +0, 14, 14, 1, 79360, 0xe7a284e6 +0, 15, 15, 1, 79360, 0xd4e5e513 +0, 16, 16, 1, 79360, 0x0a952ab1 +0, 17, 17, 1, 79360, 0x3b21c91c +0, 18, 18, 1, 79360, 0x943656cb +0, 19, 19, 1, 79360, 0xffbdb94b +0, 20, 20, 1, 79360, 0x74976e16 diff --git a/tests/ref/lavf-fate/mp3 b/tests/ref/lavf-fate/mp3 index 91e2b48c03..361314b2ca 100644 --- a/tests/ref/lavf-fate/mp3 +++ b/tests/ref/lavf-fate/mp3 @@ -1,3 +1,3 @@ -40a4e41ae74ec8dacdf02402831a6a58 *./tests/data/lavf-fate/lavf.mp3 -97230 ./tests/data/lavf-fate/lavf.mp3 +7fcf80c2059b5c058a6cdd2e2f798b6c *./tests/data/lavf-fate/lavf.mp3 +96366 ./tests/data/lavf-fate/lavf.mp3 ./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx index 1196934836..70371d8115 100644 --- a/tests/ref/lavf/dpx +++ b/tests/ref/lavf/dpx @@ -1,9 +1,9 @@ -808ea110635774252439722a48329d61 *./tests/data/images/dpx/02.dpx +d2f0b4e854fda2d3b3bee84cef80593c *./tests/data/images/dpx/02.dpx ./tests/data/images/dpx/%02d.dpx CRC=0x6da01946 305792 ./tests/data/images/dpx/02.dpx -5e1a777fa3f4094c9c4dd989cf9e8e8b *./tests/data/images/dpx/02.dpx +075963c3c08978b6a20555ba09161434 *./tests/data/images/dpx/02.dpx ./tests/data/images/dpx/%02d.dpx CRC=0xe5b9c023 609920 ./tests/data/images/dpx/02.dpx -13dc41b1e1e36399a5e1f8b7e3344a81 *./tests/data/images/dpx/02.dpx +b9f22728f8ff393bf30cf6cbd624fa95 *./tests/data/images/dpx/02.dpx ./tests/data/images/dpx/%02d.dpx CRC=0xf0a1c097 407168 ./tests/data/images/dpx/02.dpx diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv index d92aaa8c81..ee115d21a6 100644 --- a/tests/ref/lavf/mkv +++ b/tests/ref/lavf/mkv @@ -1,3 +1,3 @@ -84dcb326fe85aeeb5768beb44372f248 *./tests/data/lavf/lavf.mkv -320297 ./tests/data/lavf/lavf.mkv +0f78dd9299210a51b18faafc971e71f2 *./tests/data/lavf/lavf.mkv +320265 ./tests/data/lavf/lavf.mkv ./tests/data/lavf/lavf.mkv CRC=0x4780846b diff --git a/tests/ref/lavfi/pp3 b/tests/ref/lavfi/pp3 index ccf2eebc62..1af87610c8 100644 --- a/tests/ref/lavfi/pp3 +++ b/tests/ref/lavfi/pp3 @@ -1 +1 @@ -pp3 39af1a30d0ea0e906df264773adfcaa6 +pp3 c8277ef31ab01bad51356841c9634522 diff --git a/tests/ref/seek/lavf-mkv b/tests/ref/seek/lavf-mkv index 681462cccc..f03bcf83d6 100644 --- a/tests/ref/seek/lavf-mkv +++ b/tests/ref/seek/lavf-mkv @@ -1,48 +1,48 @@ -ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 555 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 523 size: 208 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834 ret: 0 st: 0 flags:0 ts: 0.788000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834 ret: 0 st: 0 flags:1 ts:-0.317000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 ret:-1 st: 1 flags:0 ts: 2.577000 ret: 0 st: 1 flags:1 ts: 1.471000 -ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320026 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 319994 size: 209 ret: 0 st:-1 flags:0 ts: 0.365002 -ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146738 size: 27925 +ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146706 size: 27925 ret: 0 st:-1 flags:1 ts:-0.740831 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 ret:-1 st: 0 flags:0 ts: 2.153000 ret: 0 st: 0 flags:1 ts: 1.048000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834 ret: 0 st: 1 flags:0 ts:-0.058000 -ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 555 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 523 size: 208 ret: 0 st: 1 flags:1 ts: 2.836000 -ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320026 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 319994 size: 209 ret:-1 st:-1 flags:0 ts: 1.730004 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146738 size: 27925 +ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146706 size: 27925 ret: 0 st: 0 flags:0 ts:-0.482000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 ret: 0 st: 0 flags:1 ts: 2.413000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834 ret:-1 st: 1 flags:0 ts: 1.307000 ret: 0 st: 1 flags:1 ts: 0.201000 -ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 555 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 523 size: 208 ret: 0 st:-1 flags:0 ts:-0.904994 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 ret: 0 st:-1 flags:1 ts: 1.989173 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834 ret: 0 st: 0 flags:0 ts: 0.883000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292185 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292153 size: 27834 ret: 0 st: 0 flags:1 ts:-0.222000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 ret:-1 st: 1 flags:0 ts: 2.672000 ret: 0 st: 1 flags:1 ts: 1.566000 -ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320026 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 319994 size: 209 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146738 size: 27925 +ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146706 size: 27925 ret: 0 st:-1 flags:1 ts:-0.645825 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 771 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 739 size: 27837 diff --git a/tests/ref/vsynth/vsynth1-avui b/tests/ref/vsynth/vsynth1-avui index 03f2b31c38..e4434e88d0 100644 --- a/tests/ref/vsynth/vsynth1-avui +++ b/tests/ref/vsynth/vsynth1-avui @@ -1,4 +1,4 @@ -853dad3a1248614c6d61c2f9dc2a999c *tests/data/fate/vsynth1-avui.mov -42624907 tests/data/fate/vsynth1-avui.mov +0e71be51f4e0701d91ff7fa4d9ea0533 *tests/data/fate/vsynth1-avui.mov +42624917 tests/data/fate/vsynth1-avui.mov c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-avui.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-dnxhd-1080i b/tests/ref/vsynth/vsynth1-dnxhd-1080i index 899ef9ee07..dbe2c371e0 100644 --- a/tests/ref/vsynth/vsynth1-dnxhd-1080i +++ b/tests/ref/vsynth/vsynth1-dnxhd-1080i @@ -1,4 +1,4 @@ -9a4781b0a052d9efaafbaf8893db9632 *tests/data/fate/vsynth1-dnxhd-1080i.mov +124c991ee3ac0caef39a58a45287a762 *tests/data/fate/vsynth1-dnxhd-1080i.mov 3031911 tests/data/fate/vsynth1-dnxhd-1080i.mov -e55bf857297ba4d911a9d17a984b125d *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo +a09132c6db44f415e831dcaa630a351b *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo stddev: 6.29 PSNR: 32.15 MAXDIFF: 64 bytes: 7603200/ 760320 diff --git a/tests/ref/vsynth/vsynth2-avui b/tests/ref/vsynth/vsynth2-avui index 59bac8d604..743c6ffbdb 100644 --- a/tests/ref/vsynth/vsynth2-avui +++ b/tests/ref/vsynth/vsynth2-avui @@ -1,4 +1,4 @@ -d6ed112daf14e73ea50f1c32ecc6d4ce *tests/data/fate/vsynth2-avui.mov -42624907 tests/data/fate/vsynth2-avui.mov +ec8b12fd9f1f7737f7e23419457fe431 *tests/data/fate/vsynth2-avui.mov +42624917 tests/data/fate/vsynth2-avui.mov dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-avui.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-dnxhd-1080i b/tests/ref/vsynth/vsynth2-dnxhd-1080i index 874e60bc55..f657eb4c95 100644 --- a/tests/ref/vsynth/vsynth2-dnxhd-1080i +++ b/tests/ref/vsynth/vsynth2-dnxhd-1080i @@ -1,4 +1,4 @@ -93b878dcf8f2ecc9798d0e0885c9eec9 *tests/data/fate/vsynth2-dnxhd-1080i.mov +5d7ab75ce6e547ed63a7a0eacf18f078 *tests/data/fate/vsynth2-dnxhd-1080i.mov 3031911 tests/data/fate/vsynth2-dnxhd-1080i.mov -27edc8dfe2ca19097c7f9119705b3a60 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo +744ba46da5d4c19a28562ea31061d170 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 7603200/ 760320 diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c index c9aa6e8287..30086fc0fd 100644 --- a/tools/qt-faststart.c +++ b/tools/qt-faststart.c @@ -235,8 +235,8 @@ int main(int argc, char *argv[]) goto error_out; } offset_count = BE_32(&moov_atom[i + 8]); - if (i + 12LL + offset_count * 4LL > moov_atom_size) { - printf(" bad atom size\n"); + if (i + 12 + offset_count * UINT64_C(4) > moov_atom_size) { + printf(" bad atom size/element count\n"); goto error_out; } for (j = 0; j < offset_count; j++) { @@ -256,8 +256,8 @@ int main(int argc, char *argv[]) goto error_out; } offset_count = BE_32(&moov_atom[i + 8]); - if (i + 12LL + offset_count * 8LL > moov_atom_size) { - printf(" bad atom size\n"); + if (i + 12 + offset_count * UINT64_C(8) > moov_atom_size) { + printf(" bad atom size/element count\n"); goto error_out; } for (j = 0; j < offset_count; j++) { diff --git a/version.sh b/version.sh index 8d084c2df3..2309176f7a 100755 --- a/version.sh +++ b/version.sh @@ -2,7 +2,11 @@ # check for git short hash if ! test "$revision"; then - revision=$(cd "$1" && git describe --tags --match N 2> /dev/null) + if (cd "$1" && grep git RELEASE 2> /dev/null >/dev/null) ; then + revision=$(cd "$1" && git describe --tags --match N 2> /dev/null) + else + revision=$(cd "$1" && git describe --tags --always 2> /dev/null) + fi fi # Shallow Git clones (--depth) do not have the N tag: