diff --git a/.gitignore b/.gitignore index 3e8ed0046e..bff585e806 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,10 @@ *-example *-test *_g +*.def +*.dll +*.lib +*.exp config.* doc/*.1 doc/*.html diff --git a/Changelog b/Changelog deleted file mode 100644 index 4362371aeb..0000000000 --- a/Changelog +++ /dev/null @@ -1,706 +0,0 @@ -Entries are sorted chronologically from oldest to youngest within each release, -releases are sorted from youngest to oldest. - - -version 0.7: - -- many many things we forgot because we rather write code than changelogs -- 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 - - -version 0.7_beta2: - -- 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 -- DPX image encoder -- 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 - - -version 0.7_beta1: - -- 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 -- 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 -- 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 asm functions -- MJPEG/AVI1 to JPEG/JFIF bitstream filter -- ASS subtitle encoder and decoder -- IEC 61937 encapsulation for E-AC3, 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 - - -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/ouput) -- 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/Doxyfile b/Doxyfile index cadb158f1e..be951830ef 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.5.6 +# Doxyfile 1.7.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project @@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 0.7.17 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -54,11 +54,11 @@ CREATE_SUBDIRS = NO # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, -# and Ukrainian. +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English @@ -155,13 +155,6 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. @@ -214,6 +207,18 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and @@ -268,6 +273,22 @@ SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -366,6 +387,12 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. @@ -385,6 +412,16 @@ SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. @@ -459,7 +496,8 @@ SHOW_DIRECTORIES = NO SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES @@ -474,6 +512,15 @@ SHOW_NAMESPACES = YES FILE_VERSION_FILTER = +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -577,7 +624,8 @@ EXCLUDE_SYMLINKS = NO # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = *.git *.d +EXCLUDE_PATTERNS = *.git \ + *.d # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -591,14 +639,15 @@ EXCLUDE_SYMBOLS = # directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = libavcodec/ \ + libavformat/ # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = *-example.c # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude @@ -618,14 +667,17 @@ IMAGE_PATH = # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. @@ -675,7 +727,8 @@ REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. +# link to the source code. +# Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES @@ -758,18 +811,50 @@ HTML_FOOTER = HTML_STYLESHEET = +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). -GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 @@ -779,6 +864,8 @@ GENERATE_HTMLHELP = NO # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. GENERATE_DOCSET = NO @@ -796,13 +883,22 @@ DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. -HTML_DYNAMIC_SECTIONS = NO +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You @@ -841,6 +937,76 @@ BINARY_TOC = NO TOC_EXPAND = NO +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. @@ -854,27 +1020,30 @@ ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated +# If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hiererachy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need @@ -883,6 +1052,34 @@ TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- @@ -900,6 +1097,9 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. LATEX_CMD_NAME = latex @@ -959,6 +1159,13 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1095,8 +1302,10 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. @@ -1158,16 +1367,22 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = __attribute__(x)="" "RENAME(x)=x ## _TMPL" "DEF(x)=x ## _TMPL" \ - HAVE_AV_CONFIG_H HAVE_MMX HAVE_MMX2 HAVE_AMD3DNOW \ +PREDEFINED = "__attribute__(x)=" \ + "RENAME(x)=x ## _TMPL" \ + "DEF(x)=x ## _TMPL" \ + HAVE_AV_CONFIG_H \ + HAVE_MMX \ + HAVE_MMX2 \ + HAVE_AMD3DNOW \ + "DECLARE_ALIGNED(a,t,n)=t n" \ + "offsetof(x,y)=0x42" # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -#EXPAND_AS_DEFINED = FF_COMMON_FRAME -EXPAND_AS_DEFINED = declare_idct(idct, table, idct_row_head, idct_row, idct_row_tail, idct_row_mid) +EXPAND_AS_DEFINED = declare_idct # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone @@ -1185,9 +1400,11 @@ SKIP_FUNCTION_MACROS = YES # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: -# TAGFILES = file1 file2 ... +# +# TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... +# +# TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. @@ -1255,6 +1472,14 @@ HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need @@ -1266,6 +1491,11 @@ HAVE_DOT = NO DOT_FONTNAME = FreeSans +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot @@ -1383,10 +1613,10 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is enabled by default, which results in a transparent -# background. Warning: Depending on the platform used, enabling this option -# may lead to badly anti-aliased labels on the edges of a graph (i.e. they -# become hard to read). +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES @@ -1408,12 +1638,3 @@ GENERATE_LEGEND = YES # the various graphs. DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/LICENSE b/LICENSE index 8d4d6515b0..7272b90f8d 100644 --- a/LICENSE +++ b/LICENSE @@ -41,6 +41,6 @@ is incompatible with the LGPL v2.1 and the GPL v2, but not with version 3 of those licenses. So to combine the OpenCORE libraries with FFmpeg, the license version needs to be upgraded by passing --enable-version3 to configure. -The nonfree external library libfaac can be hooked up in FFmpeg. You need to -pass --enable-nonfree to configure to enable it. Employ this option with care -as FFmpeg then becomes nonfree and unredistributable. +The nonfree external libraries libfaac and libaacplus can be hooked up in FFmpeg. +You need to pass --enable-nonfree to configure to enable it. Employ this option +with care as FFmpeg then becomes nonfree and unredistributable. diff --git a/MAINTAINERS b/MAINTAINERS index 8588ba73ad..d975553bdb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8,7 +8,6 @@ FFmpeg code. Project Leader ============== -Michael Niedermayer final design decisions @@ -19,7 +18,7 @@ ffmpeg: ffmpeg.c Michael Niedermayer ffplay: - ffplay.c Michael Niedermayer + ffplay.c Marton Balint ffprobe: ffprobe.c Stefano Sabatini @@ -373,6 +372,7 @@ Ben Littler 3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C Benoit Fouet B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8 Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7 Diego Biurrun 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5 +Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4 Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368 Justin Ruggles 3136 ECC0 C10D 6C04 5F43 CA29 FCBE CD2A 3787 1EBF Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE diff --git a/Makefile b/Makefile index 64739bd8fe..820baea99a 100644 --- a/Makefile +++ b/Makefile @@ -178,7 +178,7 @@ testclean: clean:: testclean $(RM) $(ALLPROGS) $(ALLPROGS_G) $(RM) $(CLEANSUFFIXES) - $(RM) doc/*.html doc/*.pod doc/*.1 + $(RM) doc/*.html doc/*.pod doc/*.1 doc/*.d doc/*~ $(RM) $(TOOLS) $(RM) $(CLEANSUFFIXES:%=tools/%) @@ -258,9 +258,12 @@ FATE_SEEK = $(SEEK_TESTS:seek_%=fate-seek-%) FATE = $(FATE_ACODEC) \ $(FATE_VCODEC) \ $(FATE_LAVF) \ - $(FATE_LAVFI) \ $(FATE_SEEK) \ +FATE-$(CONFIG_AVFILTER) += $(FATE_LAVFI) + +FATE += $(FATE-yes) + $(filter-out %-aref,$(FATE_ACODEC)): $(AREF) $(filter-out %-vref,$(FATE_VCODEC)): $(VREF) $(FATE_LAVF): $(REFS) @@ -282,7 +285,7 @@ fate-lavfi: $(FATE_LAVFI) fate-seek: $(FATE_SEEK) ifdef SAMPLES -FATE += $(FATE_TESTS) +FATE += $(FATE_TESTS) $(FATE_TESTS-yes) fate-rsync: rsync -vaLW rsync://fate-suite.libav.org/fate-suite/ $(SAMPLES) else diff --git a/RELEASE b/RELEASE index eb49d7c7fd..b22af294b9 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -0.7 +0.7.17 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000..b22af294b9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.7.17 diff --git a/cmdutils.c b/cmdutils.c index cd6d13346d..21922ae304 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -57,7 +57,7 @@ AVFormatContext *avformat_opts; struct SwsContext *sws_opts; AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; -static const int this_year = 2011; +static const int this_year = 2015; void init_opts(void) { @@ -574,12 +574,13 @@ void show_banner(void) print_all_libs_info(stderr, INDENT|SHOW_VERSION); } -void show_version(void) { +int opt_version(const char *opt, const char *arg) { printf("%s " FFMPEG_VERSION "\n", program_name); print_all_libs_info(stdout, SHOW_VERSION); + return 0; } -void show_license(void) +int opt_license(const char *opt, const char *arg) { printf( #if CONFIG_NONFREE @@ -646,9 +647,10 @@ void show_license(void) program_name, program_name, program_name #endif ); + return 0; } -void show_formats(void) +int opt_formats(const char *opt, const char *arg) { AVInputFormat *ifmt=NULL; AVOutputFormat *ofmt=NULL; @@ -695,9 +697,10 @@ void show_formats(void) name, long_name ? long_name:" "); } + return 0; } -void show_codecs(void) +int opt_codecs(const char *opt, const char *arg) { AVCodec *p=NULL, *p2; const char *last_name; @@ -771,9 +774,10 @@ void show_codecs(void) "even though both encoding and decoding are supported. For example, the h263\n" "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n" "worse.\n"); + return 0; } -void show_bsfs(void) +int opt_bsfs(const char *opt, const char *arg) { AVBitStreamFilter *bsf=NULL; @@ -781,9 +785,10 @@ void show_bsfs(void) while((bsf = av_bitstream_filter_next(bsf))) printf("%s\n", bsf->name); printf("\n"); + return 0; } -void show_protocols(void) +int opt_protocols(const char *opt, const char *arg) { URLProtocol *up=NULL; @@ -799,9 +804,10 @@ void show_protocols(void) up->url_write ? 'O' : '.', up->url_seek ? 'S' : '.', up->name); + return 0; } -void show_filters(void) +int opt_filters(const char *opt, const char *arg) { AVFilter av_unused(**filter) = NULL; @@ -810,9 +816,10 @@ void show_filters(void) while ((filter = av_filter_next(filter)) && *filter) printf("%-16s %s\n", (*filter)->name, (*filter)->description); #endif + return 0; } -void show_pix_fmts(void) +int opt_pix_fmts(const char *opt, const char *arg) { enum PixelFormat pix_fmt; @@ -843,6 +850,7 @@ void show_pix_fmts(void) pix_desc->nb_components, av_get_bits_per_pixel(pix_desc)); } + return 0; } int read_yesno(void) diff --git a/cmdutils.h b/cmdutils.h index e001ab9201..b05828cd0a 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -62,7 +62,7 @@ void uninit_opts(void); /** * Trivial log callback. - * Only suitable for show_help and similar since it lacks prefix handling. + * Only suitable for opt_help and similar since it lacks prefix handling. */ void log_callback_help(void* ptr, int level, const char* fmt, va_list vl); @@ -177,50 +177,58 @@ void show_banner(void); * Print the version of the program to stdout. The version message * depends on the current versions of the repository and of the libav* * libraries. + * This option processing function does not utilize the arguments. */ -void show_version(void); +int opt_version(const char *opt, const char *arg); /** * Print the license of the program to stdout. The license depends on * the license of the libraries compiled into the program. + * This option processing function does not utilize the arguments. */ -void show_license(void); +int opt_license(const char *opt, const char *arg); /** * Print a listing containing all the formats supported by the * program. + * This option processing function does not utilize the arguments. */ -void show_formats(void); +int opt_formats(const char *opt, const char *arg); /** * Print a listing containing all the codecs supported by the * program. + * This option processing function does not utilize the arguments. */ -void show_codecs(void); +int opt_codecs(const char *opt, const char *arg); /** * Print a listing containing all the filters supported by the * program. + * This option processing function does not utilize the arguments. */ -void show_filters(void); +int opt_filters(const char *opt, const char *arg); /** * Print a listing containing all the bit stream filters supported by the * program. + * This option processing function does not utilize the arguments. */ -void show_bsfs(void); +int opt_bsfs(const char *opt, const char *arg); /** * Print a listing containing all the protocols supported by the * program. + * This option processing function does not utilize the arguments. */ -void show_protocols(void); +int opt_protocols(const char *opt, const char *arg); /** * Print a listing containing all the pixel formats supported by the * program. + * This option processing function does not utilize the arguments. */ -void show_pix_fmts(void); +int opt_pix_fmts(const char *opt, const char *arg); /** * Return a positive value if a line read from standard input diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h index 9b5e5d22cd..8e680490fe 100644 --- a/cmdutils_common_opts.h +++ b/cmdutils_common_opts.h @@ -1,13 +1,13 @@ - { "L", OPT_EXIT, {(void*)show_license}, "show license" }, - { "h", OPT_EXIT, {(void*)show_help}, "show help" }, - { "?", OPT_EXIT, {(void*)show_help}, "show help" }, - { "help", OPT_EXIT, {(void*)show_help}, "show help" }, - { "-help", OPT_EXIT, {(void*)show_help}, "show help" }, - { "version", OPT_EXIT, {(void*)show_version}, "show version" }, - { "formats" , OPT_EXIT, {(void*)show_formats }, "show available formats" }, - { "codecs" , OPT_EXIT, {(void*)show_codecs }, "show available codecs" }, - { "bsfs" , OPT_EXIT, {(void*)show_bsfs }, "show available bit stream filters" }, - { "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" }, - { "filters", OPT_EXIT, {(void*)show_filters }, "show available filters" }, - { "pix_fmts" , OPT_EXIT, {(void*)show_pix_fmts }, "show available pixel formats" }, + { "L", OPT_EXIT, {(void*)opt_license}, "show license" }, + { "h", OPT_EXIT, {(void*)opt_help}, "show help" }, + { "?", OPT_EXIT, {(void*)opt_help}, "show help" }, + { "help", OPT_EXIT, {(void*)opt_help}, "show help" }, + { "-help", OPT_EXIT, {(void*)opt_help}, "show help" }, + { "version", OPT_EXIT, {(void*)opt_version}, "show version" }, + { "formats" , OPT_EXIT, {(void*)opt_formats }, "show available formats" }, + { "codecs" , OPT_EXIT, {(void*)opt_codecs }, "show available codecs" }, + { "bsfs" , OPT_EXIT, {(void*)opt_bsfs }, "show available bit stream filters" }, + { "protocols", OPT_EXIT, {(void*)opt_protocols}, "show available protocols" }, + { "filters", OPT_EXIT, {(void*)opt_filters }, "show available filters" }, + { "pix_fmts" , OPT_EXIT, {(void*)opt_pix_fmts }, "show available pixel formats" }, { "loglevel", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" }, diff --git a/configure b/configure index c9eedaf974..ed228e49a5 100755 --- a/configure +++ b/configure @@ -162,6 +162,7 @@ External library support: --enable-bzlib enable bzlib [autodetect] --enable-libcelt enable CELT/Opus decoding via libcelt [no] --enable-frei0r enable frei0r video filtering + --enable-libaacplus enable AAC+ encoding via libaacplus [no] --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no] --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no] --enable-libopencv enable video filtering via libopencv [no] @@ -177,7 +178,7 @@ External library support: --enable-libopenjpeg enable JPEG 2000 decoding via OpenJPEG [no] --enable-librtmp enable RTMP[E] support via librtmp [no] --enable-libschroedinger enable Dirac support via libschroedinger [no] - --enable-libspeex enable Speex decoding via libspeex [no] + --enable-libspeex enable Speex encoding and decoding via libspeex [no] --enable-libtheora enable Theora encoding via libtheora [no] --enable-libvo-aacenc enable AAC encoding via libvo-aacenc [no] --enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no] @@ -927,6 +928,8 @@ CONFIG_LIST=" h264pred hardcoded_tables huffman + libaacplus + libcdio libcelt libdc1394 libdirac @@ -1054,6 +1057,7 @@ HAVE_LIST=" dlfcn_h dlopen dos_paths + dxva_h ebp_available ebx_available exp2 @@ -1401,6 +1405,7 @@ vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" h264_parser_select="golomb h264dsp h264pred" # external libraries +libaacplus_encoder_deps="libaacplus" libcelt_decoder_deps="libcelt" libdirac_decoder_deps="libdirac !libschroedinger" libdirac_encoder_deps="libdirac" @@ -1417,6 +1422,7 @@ libopenjpeg_decoder_deps="libopenjpeg" libschroedinger_decoder_deps="libschroedinger" libschroedinger_encoder_deps="libschroedinger" libspeex_decoder_deps="libspeex" +libspeex_encoder_deps="libspeex" libtheora_encoder_deps="libtheora" libvo_aacenc_encoder_deps="libvo_aacenc" libvo_amrwbenc_encoder_deps="libvo_amrwbenc" @@ -1512,7 +1518,7 @@ postproc_deps="gpl" # programs ffmpeg_deps="avcodec avformat swscale" -ffmpeg_select="buffer_filter" +ffmpeg_select="buffer_filter buffersink_filter" ffplay_deps="avcodec avformat swscale sdl" ffplay_select="rdft" ffprobe_deps="avcodec avformat" @@ -1531,7 +1537,7 @@ test_deps(){ dep=${v%=*} tests=${v#*=} for name in ${tests}; do - eval ${name}_test_deps="'${dep}$suf1 ${dep}$suf2'" + append ${name}_test_deps ${dep}$suf1 ${dep}$suf2 done done } @@ -1541,6 +1547,9 @@ set_ne_test_deps(){ eval ${1}_le_test_deps="!bigendian" } +mxf_d10_test_deps="avfilter" +seek_lavf_mxf_d10_test_deps="mxf_d10_test" + test_deps _encoder _decoder \ adpcm_g726=g726 \ adpcm_ima_qt \ @@ -1603,7 +1612,7 @@ test_deps _muxer _demuxer \ mmf \ mov \ pcm_mulaw=mulaw \ - mxf \ + mxf="mxf mxf_d10" \ nut \ ogg \ rawvideo=pixfmt \ @@ -2195,7 +2204,7 @@ case "$arch" in arch="sparc" subarch="sparc64" ;; - i[3-6]86|i86pc|BePC|x86pc|x86_64|amd64) + i[3-6]86|i86pc|BePC|x86pc|x86_64|x86_32|amd64) arch="x86" ;; esac @@ -2370,7 +2379,7 @@ check_host_cflags -std=c99 check_host_cflags -Wall case "$arch" in - alpha|ia64|mips|parisc|sparc) + alpha|ia64|mips|parisc|ppc|sparc) spic=$shared ;; x86) @@ -2537,6 +2546,7 @@ case $target_os in add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_BSD_SOURCE ;; gnu) + add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 ;; qnx) add_cppflags -D_QNX_SOURCE @@ -2582,6 +2592,7 @@ die_license_disabled gpl libxavs die_license_disabled gpl libxvid die_license_disabled gpl x11grab +die_license_disabled nonfree libaacplus die_license_disabled nonfree libfaac die_license_disabled version3 libopencore_amrnb @@ -2788,6 +2799,7 @@ if enabled asm; then fi check_ldflags -Wl,--as-needed +check_ldflags -Wl,-z,noexecstack if check_func dlopen; then ldl= @@ -2849,6 +2861,7 @@ check_func_headers windows.h MapViewOfFile check_func_headers windows.h VirtualAlloc check_header dlfcn.h +check_header dxva.h check_header dxva2api.h check_header libcrystalhd/libcrystalhd_if.h check_header malloc.h @@ -2914,6 +2927,7 @@ check_mathfunc truncf enabled avisynth && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32 enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } +enabled libaacplus && require "libaacplus >= 2.0.0" aacplus.h aacplusEncOpen -laacplus enabled libdc1394 && require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdirac && require_pkg_config dirac \ "libdirac_decoder/dirac_parser.h libdirac_encoder/dirac_encoder.h" \ @@ -3064,7 +3078,6 @@ fi if enabled small; then add_cflags $size_cflags - optimizations="small" elif enabled optimizations; then add_cflags $speed_cflags else @@ -3072,6 +3085,10 @@ else fi check_cflags -fno-math-errno check_cflags -fno-signed-zeros +check_cc -mno-red-zone <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 66e5b1d deprecate url_feof e8bb2e2 deprecate url_fget_max_packet_size 76aa876 rename url_fsize -> avio_size @@ -243,7 +250,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 @@ -281,11 +288,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/RELEASE_NOTES b/doc/RELEASE_NOTES index 7861bfd4bc..536ef39f08 100644 --- a/doc/RELEASE_NOTES +++ b/doc/RELEASE_NOTES @@ -2,7 +2,7 @@ Release Notes ============= * 0.8 "Love" June, 2011 -* 0.7 "Peace" June, 2011 (identical to 0.8 but using 0.6 ABI/API) +* 0.7.1 "Peace" June, 2011 (identical to 0.8 but using 0.6 ABI/API) General notes diff --git a/doc/developer.texi b/doc/developer.texi index 69c2951620..6653a38ded 100644 --- a/doc/developer.texi +++ b/doc/developer.texi @@ -54,10 +54,8 @@ These features are supported by all compilers we care about, so we will not accept patches to remove their use unless they absolutely do not impair clarity and performance. -All code must compile with GCC 2.95 and GCC 3.3. Currently, FFmpeg also -compiles with several other compilers, such as the Compaq ccc compiler -or Sun Studio 9, and we would like to keep it that way unless it would -be exceedingly involved. To ensure compatibility, please do not use any +All code must compile with recent versions of GCC and a number of other +currently supported compilers. To ensure compatibility, please do not use additional C99 features or GCC extensions. Especially watch out for: @itemize @bullet @item diff --git a/doc/examples/muxing-example.c b/doc/examples/muxing-example.c index f068e946dd..a1f19a47bf 100644 --- a/doc/examples/muxing-example.c +++ b/doc/examples/muxing-example.c @@ -479,7 +479,7 @@ int main(int argc, char **argv) /* open the output file, if needed */ if (!(fmt->flags & AVFMT_NOFILE)) { - if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) { + if (avio_open(&oc->pb, filename, AVIO_WRONLY) < 0) { fprintf(stderr, "Could not open '%s'\n", filename); exit(1); } diff --git a/doc/faq.texi b/doc/faq.texi index 225f139b3c..daa4615a3c 100644 --- a/doc/faq.texi +++ b/doc/faq.texi @@ -447,6 +447,11 @@ encompassing your FFmpeg includes using @code{extern "C"}. See @url{http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3} +@section I'm using libavutil from within my C++ application but the compiler complains about 'UINT64_C' was not declared in this scope + +Libav is a pure C project using C99 math features, in order to enable C++ +to use them you have to append -D__STDC_CONSTANT_MACROS to your CXXFLAGS + @section I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat? You have to implement a URLProtocol, see @file{libavformat/file.c} in diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 6f21451219..95b405ccb3 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -299,6 +299,10 @@ prefix is ``ffmpeg2pass''. The complete file name will be @file{PREFIX-N.log}, where N is a number specific to the output stream. +Note that this option is overwritten by a local option of the same name +when using @code{-vcodec libx264}. That option maps to the x264 option stats +which has a different syntax. + @item -newvideo Add a new video stream to the current output stream. @@ -713,8 +717,39 @@ ffmpeg -i in.ogg -map_metadata 0:0,s0 out.mp3 Copy chapters from @var{infile} to @var{outfile}. If no chapter mapping is specified, then chapters are copied from the first input file with at least one chapter to all output files. Use a negative file index to disable any chapter copying. -@item -debug +@item -debug @var{category} Print specific debug info. +@var{category} is a number or a string containing one of the following values: +@table @samp +@item bitstream +@item buffers +picture buffer allocations +@item bugs +@item dct_coeff +@item er +error recognition +@item mb_type +macroblock (MB) type +@item mmco +memory management control operations (H.264) +@item mv +motion vector +@item pict +picture info +@item pts +@item qp +per-block quantization parameter (QP) +@item rc +rate control +@item skip +@item startcode +@item thread_ops +threading operations +@item vis_mb_type +visualize block types +@item vis_qp +visualize quantization parameter (QP), lower QP are tinted greener +@end table @item -benchmark Show benchmarking information at the end of an encode. Shows CPU time used and maximum memory consumption. diff --git a/doc/filters.texi b/doc/filters.texi index eb31714486..1ebaac1adf 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -82,7 +82,7 @@ Follows a BNF description for the filtergraph syntax: @var{LINKLABEL} ::= "[" @var{NAME} "]" @var{LINKLABELS} ::= @var{LINKLABEL} [@var{LINKLABELS}] @var{FILTER_ARGUMENTS} ::= sequence of chars (eventually quoted) -@var{FILTER} ::= [@var{LINKNAMES}] @var{NAME} ["=" @var{ARGUMENTS}] [@var{LINKNAMES}] +@var{FILTER} ::= [@var{LINKLABELS}] @var{NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}] @var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] @var{FILTERGRAPH} ::= @var{FILTERCHAIN} [;@var{FILTERGRAPH}] @end example @@ -1683,7 +1683,7 @@ It accepts the following parameters: Negative values for the amount will blur the input video, while positive values will sharpen. All parameters are optional and default to the -equivalent of the string '5:5:1.0:0:0:0.0'. +equivalent of the string '5:5:1.0:5:5:0.0'. @table @option @@ -1701,11 +1701,11 @@ and 5.0, default value is 1.0. @item chroma_msize_x Set the chroma matrix horizontal size. It can be an integer between 3 -and 13, default value is 0. +and 13, default value is 5. @item chroma_msize_y Set the chroma matrix vertical size. It can be an integer between 3 -and 13, default value is 0. +and 13, default value is 5. @item luma_amount Set the chroma effect strength. It can be a float number between -2.0 @@ -1760,9 +1760,9 @@ interlaced video, accepts one of the following values: @table @option @item 0 -assume bottom field first -@item 1 assume top field first +@item 1 +assume bottom field first @item -1 enable automatic detection @end table diff --git a/doc/general.texi b/doc/general.texi index e5e76db056..db78efef78 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -542,6 +542,8 @@ following image formats are supported: @multitable @columnfractions .4 .1 .1 .4 @item Name @tab Encoding @tab Decoding @tab Comments @item 8SVX audio @tab @tab X +@item AAC+ @tab E @tab X + @tab encoding supported through external library libaacplus @item AAC @tab E @tab X @tab encoding supported through external library libfaac and libvo-aacenc @item AC-3 @tab IX @tab X @@ -961,7 +963,7 @@ MSVC++-compatible import libraries. @item Build FFmpeg with @example -./configure --enable-shared --enable-memalign-hack +./configure --enable-shared make make install @end example @@ -998,9 +1000,11 @@ extern __declspec(dllimport) const AVPixFmtDescriptor av_pix_fmt_descriptors[]; Note that using import libraries created by dlltool requires the linker optimization option to be set to -"References: Keep Unreferenced Data (/OPT:NOREF)", otherwise +"References: Keep Unreferenced Data (@code{/OPT:NOREF})", otherwise the resulting binaries will fail during runtime. This isn't required when using import libraries generated by lib.exe. +This issue is reported upstream at +@url{http://sourceware.org/bugzilla/show_bug.cgi?id=12633}. @subsection Cross compilation for Windows with Linux @@ -1036,7 +1040,7 @@ diffutils Then run @example -./configure --enable-static --disable-shared +./configure @end example to make a static build. @@ -1058,7 +1062,7 @@ These library packages are only available from Cygwin Ports (@url{http://sourceware.org/cygwinports/}) : @example -yasm, libSDL-devel, libdirac-devel, libfaac-devel, libgsm-devel, +yasm, libSDL-devel, libdirac-devel, libfaac-devel, libaacplus-devel, libgsm-devel, libmp3lame-devel, libschroedinger1.0-devel, speex-devel, libtheora-devel, libxvidcore-devel @end example @@ -1083,12 +1087,12 @@ and add some special flags to your configure invocation. For a static build run @example -./configure --target-os=mingw32 --enable-memalign-hack --enable-static --disable-shared --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin +./configure --target-os=mingw32 --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin @end example and for a build with shared libraries @example -./configure --target-os=mingw32 --enable-memalign-hack --enable-shared --disable-static --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin +./configure --target-os=mingw32 --enable-shared --disable-static --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin @end example @bye diff --git a/doc/issue_tracker.txt b/doc/issue_tracker.txt index a41b8e5044..32a2c8c59c 100644 --- a/doc/issue_tracker.txt +++ b/doc/issue_tracker.txt @@ -15,7 +15,7 @@ be properly added to the respective 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 NOTE: issue = (bug report || patch || feature request) diff --git a/ffmpeg.c b/ffmpeg.c index 80a67c180e..867ac75d17 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -31,7 +31,7 @@ #include "libavformat/avformat.h" #include "libavdevice/avdevice.h" #include "libswscale/swscale.h" -#include "libavutil/opt.h" +#include "libavcodec/opt.h" #include "libavcodec/audioconvert.h" #include "libavutil/audioconvert.h" #include "libavutil/parseutils.h" @@ -113,7 +113,9 @@ typedef struct AVChapterMap { static const OptionDef options[]; #define MAX_FILES 100 +#if !FF_API_MAX_STREAMS #define MAX_STREAMS 1024 /* arbitrary sanity check value */ +#endif static const char *last_asked_format = NULL; static int64_t input_files_ts_offset[MAX_FILES]; @@ -313,6 +315,7 @@ typedef struct AVOutputStream { #endif int sws_flags; + char *forced_key_frames; } AVOutputStream; static AVOutputStream **output_streams_for_file[MAX_FILES] = { NULL }; @@ -343,6 +346,7 @@ typedef struct AVInputFile { int eof_reached; /* true if eof reached */ int ist_index; /* index of first stream in ist_table */ int buffer_size; /* current total buffer size */ + int nb_streams; /* nb streams we are aware of */ } AVInputFile; #if HAVE_TERMIOS_H @@ -711,7 +715,6 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) return err; /* copy stream format */ s->nb_streams = 0; - s->streams = av_mallocz(sizeof(AVStream *) * ic->nb_streams); for(i=0;inb_streams;i++) { AVStream *st; AVCodec *codec; @@ -1859,7 +1862,7 @@ static int output_packet(AVInputStream *ist, int ist_index, ret = 0; /* encode any samples remaining in fifo */ if (fifo_bytes > 0) { - int osize = av_get_bits_per_sample_fmt(enc->sample_fmt) >> 3; + int osize = av_get_bytes_per_sample(enc->sample_fmt); int fs_tmp = enc->frame_size; av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); @@ -2045,7 +2048,7 @@ static int transcode(AVFormatContext **output_files, int si = stream_maps[i].stream_index; if (fi < 0 || fi > nb_input_files - 1 || - si < 0 || si > input_files[fi].ctx->nb_streams - 1) { + si < 0 || si > input_files[fi].nb_streams - 1) { fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si); ret = AVERROR(EINVAL); goto fail; @@ -2053,7 +2056,7 @@ static int transcode(AVFormatContext **output_files, fi = stream_maps[i].sync_file_index; si = stream_maps[i].sync_stream_index; if (fi < 0 || fi > nb_input_files - 1 || - si < 0 || si > input_files[fi].ctx->nb_streams - 1) { + si < 0 || si > input_files[fi].nb_streams - 1) { fprintf(stderr,"Could not find sync stream #%d.%d\n", fi, si); ret = AVERROR(EINVAL); goto fail; @@ -2303,16 +2306,19 @@ static int transcode(AVFormatContext **output_files, fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); ffmpeg_exit(1); } + + if (!codec->width || !codec->height) { + codec->width = icodec->width; + codec->height = icodec->height; + } + ost->video_resample = codec->width != icodec->width || codec->height != icodec->height || codec->pix_fmt != icodec->pix_fmt; if (ost->video_resample) { codec->bits_per_raw_sample= frame_bits_per_raw_sample; } - if (!codec->width || !codec->height) { - codec->width = icodec->width; - codec->height = icodec->height; - } + ost->resample_height = icodec->height; ost->resample_width = icodec->width; ost->resample_pix_fmt= icodec->pix_fmt; @@ -2332,6 +2338,9 @@ static int transcode(AVFormatContext **output_files, "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n"); } + if (ost->forced_key_frames) + parse_forced_key_frames(ost->forced_key_frames, ost, codec); + #if CONFIG_AVFILTER if (configure_video_filters(ist, ost)) { fprintf(stderr, "Error opening filters!\n"); @@ -2375,9 +2384,9 @@ static int transcode(AVFormatContext **output_files, } } if(codec->codec_type == AVMEDIA_TYPE_VIDEO){ - /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */ + /* maximum video buffer size is 6-bytes per pixel, plus DPX header size (1664)*/ int size= codec->width * codec->height; - bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664); + bit_buffer_size= FFMAX(bit_buffer_size, 7*size + 10000); } } @@ -2728,7 +2737,7 @@ static int transcode(AVFormatContext **output_files, } /* the following test is needed in case new streams appear dynamically in stream : we ignore them */ - if (pkt.stream_index >= input_files[file_index].ctx->nb_streams) + if (pkt.stream_index >= input_files[file_index].nb_streams) goto discard_packet; ist_index = input_files[file_index].ist_index + pkt.stream_index; ist = &input_streams[ist_index]; @@ -2853,6 +2862,7 @@ static int transcode(AVFormatContext **output_files, av_freep(&ost->st->codec->subtitle_header); av_free(ost->resample_frame.data[0]); av_free(ost->forced_kf_pts); + av_free(ost->forced_key_frames); if (ost->video_resample) sws_freeContext(ost->img_resample_ctx); if (ost->resample) @@ -2941,7 +2951,7 @@ static int opt_frame_pix_fmt(const char *opt, const char *arg) return AVERROR(EINVAL); } } else { - show_pix_fmts(); + opt_pix_fmts(NULL, NULL); ffmpeg_exit(0); } return 0; @@ -3465,6 +3475,7 @@ static int opt_input_file(const char *opt, const char *filename) input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1); input_files[nb_input_files - 1].ctx = ic; input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; + input_files[nb_input_files - 1].nb_streams = ic->nb_streams; top_field_first = -1; video_channel = 0; @@ -3650,8 +3661,10 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) } } - if (forced_key_frames) - parse_forced_key_frames(forced_key_frames, ost, video_enc); + if (forced_key_frames) { + ost->forced_key_frames = forced_key_frames; + forced_key_frames = NULL; + } } if (video_language) { av_dict_set(&st->metadata, "language", video_language, 0); @@ -3661,7 +3674,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) /* reset some key parameters */ video_disable = 0; av_freep(&video_codec_name); - av_freep(&forced_key_frames); video_stream_copy = 0; frame_pix_fmt = PIX_FMT_NONE; } @@ -3952,7 +3964,7 @@ static int opt_output_file(const char *opt, const char *filename) /* check filename in case of an image number is expected */ if (oc->oformat->flags & AVFMT_NEEDNUMBER) { if (!av_filename_number_test(oc->filename)) { - print_error(oc->filename, AVERROR(EINVAL)); + print_error(oc->filename, AVERROR_NUMEXPECTED); ffmpeg_exit(1); } } @@ -3963,7 +3975,7 @@ static int opt_output_file(const char *opt, const char *filename) (strchr(filename, ':') == NULL || filename[1] == ':' || av_strstart(filename, "file:", NULL))) { - if (avio_check(filename, 0) == 0) { + if (url_exist(filename)) { if (!using_stdin) { fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename); fflush(stderr); @@ -3980,7 +3992,7 @@ static int opt_output_file(const char *opt, const char *filename) } /* open the file */ - if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { + if ((err = avio_open(&oc->pb, filename, AVIO_WRONLY)) < 0) { print_error(filename, err); ffmpeg_exit(1); } @@ -4071,16 +4083,18 @@ static void parse_matrix_coeffs(uint16_t *dest, const char *str) } } -static void opt_inter_matrix(const char *arg) +static int opt_inter_matrix(const char *opt, const char *arg) { inter_matrix = av_mallocz(sizeof(uint16_t) * 64); parse_matrix_coeffs(inter_matrix, arg); + return 0; } -static void opt_intra_matrix(const char *arg) +static int opt_intra_matrix(const char *opt, const char *arg) { intra_matrix = av_mallocz(sizeof(uint16_t) * 64); parse_matrix_coeffs(intra_matrix, arg); + return 0; } static void show_usage(void) @@ -4090,7 +4104,7 @@ static void show_usage(void) printf("\n"); } -static void show_help(void) +static int opt_help(const char *opt, const char *arg) { AVCodec *c; AVOutputFormat *oformat = NULL; @@ -4145,6 +4159,7 @@ static void show_help(void) } av_opt_show2(sws_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0); + return 0; } static int opt_target(const char *opt, const char *arg) @@ -4375,10 +4390,14 @@ static void log_callback_null(void* ptr, int level, const char* fmt, va_list vl) { } -static void opt_passlogfile(const char *arg) +static int opt_passlogfile(const char *opt, const char *arg) { pass_logfilename_prefix = arg; - opt_default("passlogfile", arg); +#if CONFIG_LIBX264_ENCODER + return opt_default("passlogfile", arg); +#else + return 0; +#endif } static const OptionDef options[] = { diff --git a/ffplay.c b/ffplay.c index 96a8517b98..dabd032fd7 100644 --- a/ffplay.c +++ b/ffplay.c @@ -27,6 +27,7 @@ #include "libavutil/colorspace.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" +#include "libavutil/dict.h" #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavutil/avassert.h" @@ -34,7 +35,7 @@ #include "libavdevice/avdevice.h" #include "libswscale/swscale.h" #include "libavcodec/audioconvert.h" -#include "libavutil/opt.h" +#include "libavcodec/opt.h" #include "libavcodec/avfft.h" #if CONFIG_AVFILTER @@ -211,7 +212,7 @@ typedef struct VideoState { int refresh; } VideoState; -static void show_help(void); +static int opt_help(const char *opt, const char *arg); /* options specified by the user */ static AVInputFormat *file_iformat; @@ -1778,8 +1779,10 @@ static int video_thread(void *arg) if (ret < 0) goto the_end; +#if CONFIG_AVFILTER if (!picref) continue; +#endif pts = pts_int*av_q2d(is->video_st->time_base); @@ -2132,7 +2135,12 @@ static int stream_component_open(VideoState *is, int stream_index) avctx->workaround_bugs = workaround_bugs; avctx->lowres = lowres; - if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE; + if(avctx->lowres > codec->max_lowres){ + av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n", + codec->max_lowres); + avctx->lowres= codec->max_lowres; + } + if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE; avctx->idct_algo= idct; if(fast) avctx->flags2 |= CODEC_FLAG2_FAST; avctx->skip_frame= skip_frame; @@ -2295,15 +2303,13 @@ static int decode_interrupt_cb(void) static int read_thread(void *arg) { VideoState *is = arg; - AVFormatContext *ic; + AVFormatContext *ic = NULL; int err, i, ret; int st_index[AVMEDIA_TYPE_NB]; AVPacket pkt1, *pkt = &pkt1; - AVFormatParameters params, *ap = ¶ms; int eof=0; int pkt_in_play_range = 0; - - ic = avformat_alloc_context(); + AVDictionaryEntry *t; memset(st_index, -1, sizeof(st_index)); is->video_stream = -1; @@ -2313,30 +2319,17 @@ static int read_thread(void *arg) global_video_state = is; avio_set_interrupt_cb(decode_interrupt_cb); - memset(ap, 0, sizeof(*ap)); - - ap->prealloced_context = 1; - ap->width = frame_width; - ap->height= frame_height; - ap->time_base= (AVRational){1, 25}; - ap->pix_fmt = frame_pix_fmt; - ic->flags |= AVFMT_FLAG_PRIV_OPT; - - - err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap); - if (err >= 0) { - set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); - err = av_demuxer_open(ic, ap); - if(err < 0){ - avformat_free_context(ic); - ic= NULL; - } - } + err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts); if (err < 0) { print_error(is->filename, err); ret = -1; goto fail; } + if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { + av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); + ret = AVERROR_OPTION_NOT_FOUND; + goto fail; + } is->ic = ic; if(genpts) @@ -2964,7 +2957,7 @@ static void show_usage(void) printf("\n"); } -static void show_help(void) +static int opt_help(const char *opt, const char *arg) { av_log_set_callback(log_callback_help); show_usage(); @@ -2996,6 +2989,7 @@ static void show_help(void) "down/up seek backward/forward 1 minute\n" "mouse click seek to percentage in file corresponding to fraction of width\n" ); + return 0; } /* Called from the main */ diff --git a/ffprobe.c b/ffprobe.c index a2b27c3745..ae97253cb8 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -23,7 +23,7 @@ #include "libavformat/avformat.h" #include "libavcodec/avcodec.h" -#include "libavutil/opt.h" +#include "libavcodec/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/dict.h" #include "libavdevice/avdevice.h" @@ -353,7 +353,7 @@ static int opt_input_file(const char *opt, const char *arg) return 0; } -static void show_help(void) +static int opt_help(const char *opt, const char *arg) { av_log_set_callback(log_callback_help); show_usage(); @@ -361,6 +361,7 @@ static void show_help(void) printf("\n"); av_opt_show2(avformat_opts, NULL, AV_OPT_FLAG_DECODING_PARAM, 0); + return 0; } static void opt_pretty(void) diff --git a/ffserver.c b/ffserver.c index 15ea00f4f8..8f5c2baf72 100644 --- a/ffserver.c +++ b/ffserver.c @@ -39,7 +39,7 @@ #include "libavutil/dict.h" #include "libavutil/random_seed.h" #include "libavutil/parseutils.h" -#include "libavutil/opt.h" +#include "libavcodec/opt.h" #include #include #include @@ -94,7 +94,9 @@ static const char *http_state[] = { "RTSP_SEND_PACKET", }; +#if !FF_API_MAX_STREAMS #define MAX_STREAMS 20 +#endif #define IOBUFFER_INIT_SIZE 8192 @@ -516,6 +518,7 @@ static int socket_open_listen(struct sockaddr_in *my_addr) tmp = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); + my_addr->sin_family = AF_INET; if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) { char bindmsg[32]; snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port)); @@ -2229,11 +2232,11 @@ static int http_prepare_data(HTTPContext *c) av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0); av_dict_set(&c->fmt_ctx.metadata, "title" , c->stream->title , 0); - c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams); - for(i=0;istream->nb_streams;i++) { + AVStream *st; AVStream *src; - c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream)); + st = av_mallocz(sizeof(AVStream)); + c->fmt_ctx.streams[i] = st; /* if file or feed, then just take streams from FFStream struct */ if (!c->stream->feed || c->stream->feed == c->stream) @@ -2241,9 +2244,9 @@ static int http_prepare_data(HTTPContext *c) else src = c->stream->feed->streams[c->stream->feed_streams[i]]; - *(c->fmt_ctx.streams[i]) = *src; - c->fmt_ctx.streams[i]->priv_data = 0; - c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in + *st = *src; + st->priv_data = 0; + st->codec->frame_number = 0; /* XXX: should be done in AVStream, not in codec */ } /* set output format parameters */ @@ -2941,9 +2944,11 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, snprintf(avc->filename, 1024, "rtp://0.0.0.0"); } +#if !FF_API_MAX_STREAMS if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) || !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams)))) goto sdp_done; +#endif if (avc->nb_streams >= INT_MAX/sizeof(*avs) || !(avs = av_malloc(avc->nb_streams * sizeof(*avs)))) goto sdp_done; @@ -2956,8 +2961,10 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, av_sdp_create(&avc, 1, *pbuffer, 2048); sdp_done: +#if !FF_API_MAX_STREAMS av_free(avc->streams); - av_dict_free(&avc->metadata); +#endif + av_metadata_free(&avc->metadata); av_free(avc); av_free(avs); @@ -3385,9 +3392,6 @@ static int rtp_new_av_stream(HTTPContext *c, if (!st) goto fail; ctx->nb_streams = 1; - ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams); - if (!ctx->streams) - goto fail; ctx->streams[0] = st; if (!c->stream->feed || @@ -3421,7 +3425,7 @@ static int rtp_new_av_stream(HTTPContext *c, "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port)); } - if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0) + if (url_open(&h, ctx->filename, AVIO_WRONLY) < 0) goto fail; c->rtp_handles[stream_index] = h; max_packet_size = url_get_max_packet_size(h); @@ -3674,7 +3678,7 @@ static void build_feed_streams(void) for(feed = first_feed; feed != NULL; feed = feed->next_feed) { int fd; - if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) { + if (url_exist(feed->feed_filename)) { /* See if it matches */ AVFormatContext *s = NULL; int matches = 0; @@ -3747,7 +3751,7 @@ static void build_feed_streams(void) unlink(feed->feed_filename); } } - if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) { + if (!url_exist(feed->feed_filename)) { AVFormatContext s1 = {0}, *s = &s1; if (feed->readonly) { @@ -3757,15 +3761,20 @@ static void build_feed_streams(void) } /* only write the header of the ffm file */ - if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) { + if (avio_open(&s->pb, feed->feed_filename, AVIO_WRONLY) < 0) { http_log("Could not open output feed file '%s'\n", feed->feed_filename); exit(1); } s->oformat = feed->fmt; s->nb_streams = feed->nb_streams; - s->streams = feed->streams; - if (avformat_write_header(s, NULL) < 0) { + for(i=0;inb_streams;i++) { + AVStream *st; + st = feed->streams[i]; + s->streams[i] = st; + } + av_set_parameters(s, NULL); + if (av_write_header(s) < 0) { http_log("Container doesn't supports the required parameters\n"); exit(1); } @@ -4654,12 +4663,13 @@ static void opt_debug(void) logfilename[0] = '-'; } -static void show_help(void) +static int opt_help(const char *opt, const char *arg) { printf("usage: ffserver [options]\n" "Hyper fast multi format Audio/Video streaming server\n"); printf("\n"); show_help_options(options, "Main options:\n", 0, 0); + return 0; } static const OptionDef options[] = { diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index d89b494b09..bbddef4876 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -133,7 +133,9 @@ typedef struct FourXContext{ GetBitContext pre_gb; ///< ac/dc prefix GetBitContext gb; const uint8_t *bytestream; + const uint8_t *bytestream_end; const uint16_t *wordstream; + const uint16_t *wordstream_end; int mv[256]; VLC pre_vlc; int last_dc; @@ -277,7 +279,7 @@ static void init_mv(FourXContext *f){ } #endif -static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){ +static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, unsigned dc){ int i; dc*= 0x10001; @@ -328,6 +330,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo assert(code>=0 && code<=6); if(code == 0){ + if (f->bytestream_end - f->bytestream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return; + } src += f->mv[ *f->bytestream++ ]; if(start > src || src > end){ av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); @@ -345,15 +351,31 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo }else if(code == 3 && f->version<2){ mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ + if (f->bytestream_end - f->bytestream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return; + } src += f->mv[ *f->bytestream++ ]; if(start > src || src > end){ av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return; } + if (f->wordstream_end - f->wordstream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, av_le2ne16(*f->wordstream++)); }else if(code == 5){ + if (f->wordstream_end - f->wordstream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, av_le2ne16(*f->wordstream++)); }else if(code == 6){ + if (f->wordstream_end - f->wordstream < 2){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } if(log2w){ dst[0] = av_le2ne16(*f->wordstream++); dst[1] = av_le2ne16(*f->wordstream++); @@ -375,6 +397,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ if(f->version>1){ extra=20; + if (length < extra) + return -1; bitstream_size= AV_RL32(buf+8); wordstream_size= AV_RL32(buf+12); bytestream_size= AV_RL32(buf+16); @@ -385,11 +409,10 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0); } - if(bitstream_size+ bytestream_size+ wordstream_size + extra != length - || bitstream_size > (1<<26) - || bytestream_size > (1<<26) - || wordstream_size > (1<<26) - ){ + if (bitstream_size > length || + bytestream_size > length - bitstream_size || + wordstream_size > length - bytestream_size - bitstream_size || + extra > length - bytestream_size - bitstream_size - wordstream_size){ av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, bitstream_size+ bytestream_size+ wordstream_size - length); return -1; @@ -399,10 +422,13 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4); + memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); f->wordstream= (const uint16_t*)(buf + extra + bitstream_size); + f->wordstream_end= f->wordstream + wordstream_size/2; f->bytestream= buf + extra + bitstream_size + wordstream_size; + f->bytestream_end = f->bytestream + bytestream_size; init_mv(f); @@ -531,7 +557,7 @@ static int decode_i_mb(FourXContext *f){ return 0; } -static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){ +static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf, int buf_size){ int frequency[512]; uint8_t flag[512]; int up[512]; @@ -539,6 +565,7 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const int bits_tab[257]; int start, end; const uint8_t *ptr= buf; + const uint8_t *ptr_end = buf + buf_size; int j; memset(frequency, 0, sizeof(frequency)); @@ -549,6 +576,8 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const for(;;){ int i; + if (start <= end && ptr_end - ptr < end - start + 1 + 1) + return NULL; for(i=start; i<=end; i++){ frequency[i]= *ptr++; } @@ -601,9 +630,10 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const len_tab[j]= len; } - init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, - len_tab , 1, 1, - bits_tab, 4, 4, 0); + if (init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, + len_tab , 1, 1, + bits_tab, 4, 4, 0)) + return NULL; return ptr; } @@ -621,10 +651,13 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ const int height= f->avctx->height; uint16_t *dst= (uint16_t*)f->current_picture.data[0]; const int stride= f->current_picture.linesize[0]>>1; + const uint8_t *buf_end = buf + length; for(y=0; ycurrent_picture.data[0]; const int stride= f->current_picture.linesize[0]>>1; const unsigned int bitstream_size= AV_RL32(buf); - const int token_count av_unused = AV_RL32(buf + bitstream_size + 8); - unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4); - const uint8_t *prestream= buf + bitstream_size + 12; + unsigned int prestream_size; + const uint8_t *prestream; - if(prestream_size + bitstream_size + 12 != length - || bitstream_size > (1<<26) - || prestream_size > (1<<26)){ + if (length < bitstream_size + 12) { + av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); + return AVERROR_INVALIDDATA; + } + + prestream_size = 4 * AV_RL32(buf + bitstream_size + 4); + prestream = buf + bitstream_size + 12; + + if (prestream_size > (1<<26) || + prestream_size != length - (bitstream_size + 12)){ 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); + prestream= read_huffman_tables(f, prestream, buf + length - prestream); + if (!prestream) + return -1; init_get_bits(&f->gb, buf + 4, 8*bitstream_size); @@ -679,6 +720,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4); + memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); f->last_dc= 0*128*8*8; @@ -710,6 +752,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p, temp; int i, frame_4cc, frame_size; + if (buf_size < 12) + return AVERROR_INVALIDDATA; frame_4cc= AV_RL32(buf); if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4)); @@ -722,6 +766,11 @@ static int decode_frame(AVCodecContext *avctx, 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; + } + for(i=0; icfrm[i].id && f->cfrm[i].id < avctx->frame_number) av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); @@ -738,6 +787,8 @@ static int decode_frame(AVCodecContext *avctx, } cfrm= &f->cfrm[i]; + if (data_size > UINT_MAX - cfrm->size - FF_INPUT_BUFFER_PADDING_SIZE) + return AVERROR_INVALIDDATA; cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL av_log(f->avctx, AV_LOG_ERROR, "realloc falure"); @@ -781,12 +832,16 @@ static int decode_frame(AVCodecContext *avctx, if(frame_4cc == AV_RL32("ifr2")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i2_frame(f, buf-4, frame_size) < 0) + if(decode_i2_frame(f, buf-4, frame_size+4) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("ifrm")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i_frame(f, buf, frame_size) < 0) + if(decode_i_frame(f, buf, frame_size) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){ if(!f->last_picture.data[0]){ f->last_picture.reference= 1; @@ -797,8 +852,10 @@ static int decode_frame(AVCodecContext *avctx, } p->pict_type= AV_PICTURE_TYPE_P; - if(decode_p_frame(f, buf, frame_size) < 0) + if(decode_p_frame(f, buf, frame_size) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("snd_")){ av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); }else{ @@ -831,6 +888,10 @@ static av_cold int decode_init(AVCodecContext *avctx){ av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n"); return 1; } + if((avctx->width % 16) || (avctx->height % 16)) { + av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n"); + return AVERROR_INVALIDDATA; + } avcodec_get_frame_defaults(&f->current_picture); avcodec_get_frame_defaults(&f->last_picture); diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index 832298b98e..390ce8f72f 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -50,8 +50,6 @@ typedef struct EightBpsContext { unsigned char planes; unsigned char planemap[4]; - - uint32_t pal[256]; } EightBpsContext; @@ -131,16 +129,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac } } - if (avctx->bits_per_coded_sample <= 8) { - const uint8_t *pal = av_packet_get_side_data(avpkt, - AV_PKT_DATA_PALETTE, - NULL); - if (pal) { + if (avctx->palctrl) { + memcpy (c->pic.data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + if (avctx->palctrl->palette_changed) { c->pic.palette_has_changed = 1; - memcpy(c->pal, pal, AVPALETTE_SIZE); - } - - memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE); + avctx->palctrl->palette_changed = 0; + } else + c->pic.palette_has_changed = 0; } *data_size = sizeof(AVFrame); @@ -170,6 +165,10 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; c->planes = 1; c->planemap[0] = 0; // 1st plane is palette indexes + if (avctx->palctrl == NULL) { + av_log(avctx, AV_LOG_ERROR, "Error: PAL8 format but no palette from demuxer.\n"); + return -1; + } break; case 24: avctx->pix_fmt = avctx->get_format(avctx, pixfmt_rgb24); diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c index 5d94e005a2..336fa70852 100644 --- a/libavcodec/8svx.c +++ b/libavcodec/8svx.c @@ -44,7 +44,7 @@ typedef struct EightSvxContext { /* buffer used to store the whole audio decoded/interleaved chunk, * which is sent with the first packet */ uint8_t *samples; - size_t samples_size; + int64_t samples_size; int samples_idx; } EightSvxContext; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b6103af3c0..e30be95e77 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -15,6 +15,7 @@ OBJS = allcodecs.o \ fmtconvert.o \ imgconvert.o \ jrevdct.o \ + opt.o \ options.o \ parser.o \ raw.o \ @@ -567,6 +568,7 @@ OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \ 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_LIBDIRAC_DECODER) += libdiracdec.o OBJS-$(CONFIG_LIBDIRAC_ENCODER) += libdiracenc.o libdirac_libschro.o @@ -587,6 +589,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ libschroedinger.o \ libdirac_libschro.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o +OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o OBJS-$(CONFIG_LIBVO_AACENC_ENCODER) += libvo-aacenc.o mpeg4audio.o OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 5a665d0592..c029e9e6bf 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -55,9 +55,13 @@ static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest) for (y = blocky; y < blocky + 8 && y < C64YRES; y++) { for (x = blockx; x < blockx + 8 && x < C64XRES; x += 2) { if(x < width && y < height) { - /* build average over 2 pixels */ - luma = (src[(x + 0 + y * p->linesize[0])] + - src[(x + 1 + y * p->linesize[0])]) / 2; + if (x + 1 < width) { + /* build average over 2 pixels */ + luma = (src[(x + 0 + y * p->linesize[0])] + + src[(x + 1 + y * p->linesize[0])]) / 2; + } else { + luma = src[(x + y * p->linesize[0])]; + } /* write blocks as linear data now so they are suitable for elbg */ dest[0] = luma; } diff --git a/libavcodec/aac.h b/libavcodec/aac.h index f089ee9a29..477acb5d4e 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -258,7 +258,7 @@ typedef struct { DynamicRangeControl che_drc; /** - * @defgroup elements Channel element related data. + * @name Channel element related data * @{ */ enum ChannelPosition che_pos[4][MAX_ELEM_ID]; /**< channel element channel mapping with the @@ -270,14 +270,15 @@ typedef struct { /** @} */ /** - * @defgroup temporary aligned temporary buffers (We do not want to have these on the stack.) + * @name temporary aligned temporary buffers + * (We do not want to have these on the stack.) * @{ */ DECLARE_ALIGNED(32, float, buf_mdct)[1024]; /** @} */ /** - * @defgroup tables Computed / set up during initialization. + * @name Computed / set up during initialization * @{ */ FFTContext mdct; @@ -289,7 +290,7 @@ typedef struct { /** @} */ /** - * @defgroup output Members used for output interleaving. + * @name Members used for output interleaving * @{ */ float *output_data[MAX_CHANNELS]; ///< Points to each element's 'ret' buffer (PCM output). diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c index 6558c0280f..2e14b1a0b6 100644 --- a/libavcodec/aac_adtstoasc_bsf.c +++ b/libavcodec/aac_adtstoasc_bsf.c @@ -72,7 +72,7 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, int pce_size = 0; uint8_t pce_data[MAX_PCE_SIZE]; if (!hdr.chan_config) { - init_get_bits(&gb, buf, buf_size); + init_get_bits(&gb, buf, buf_size * 8); if (get_bits(&gb, 3) != 5) { av_log_missing_feature(avctx, "PCE based channel configuration, where the PCE is not the first syntax element is", 0); return -1; diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index cb8760801a..41c4ea262b 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -183,6 +183,8 @@ static av_cold int che_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_ELEM_ID], int type, int id, int *channels) { + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; if (che_pos[type][id]) { if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) return AVERROR(ENOMEM); @@ -568,6 +570,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) output_scale_factor = 1.0; } + 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); @@ -754,19 +761,20 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120], av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); return -1; } - while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1) + do { + sect_len_incr = get_bits(gb, bits); sect_end += sect_len_incr; - sect_end += sect_len_incr; - if (get_bits_left(gb) < 0) { - av_log(ac->avctx, AV_LOG_ERROR, overread_err); - return -1; - } - if (sect_end > ics->max_sfb) { - av_log(ac->avctx, AV_LOG_ERROR, - "Number of bands (%d) exceeds limit (%d).\n", - sect_end, ics->max_sfb); - return -1; - } + if (get_bits_left(gb) < 0) { + av_log(ac->avctx, AV_LOG_ERROR, overread_err); + return -1; + } + if (sect_end > ics->max_sfb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of bands (%d) exceeds limit (%d).\n", + sect_end, ics->max_sfb); + return -1; + } + } while (sect_len_incr == (1 << bits) - 1); for (; k < sect_end; k++) { band_type [idx] = sect_band_type; band_type_run_end[idx++] = sect_end; @@ -1090,7 +1098,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], GET_VLC(code, re, gb, vlc_tab, 8, 2); cb_idx = cb_vector_idx[code]; nnz = cb_idx >> 8 & 15; - bits = SHOW_UBITS(re, gb, nnz) << (32-nnz); + bits = nnz ? GET_CACHE(re, gb) : 0; LAST_SKIP_BITS(re, gb, nnz); cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx); } while (len -= 4); @@ -1130,7 +1138,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], GET_VLC(code, re, gb, vlc_tab, 8, 2); cb_idx = cb_vector_idx[code]; nnz = cb_idx >> 8 & 15; - sign = SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12); + sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0; LAST_SKIP_BITS(re, gb, nnz); cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx); } while (len -= 2); @@ -1693,7 +1701,7 @@ static void apply_tns(float coef[1024], TemporalNoiseShaping *tns, int w, filt, m, i; int bottom, top, order, start, end, size, inc; float lpc[TNS_MAX_ORDER]; - float tmp[TNS_MAX_ORDER]; + float tmp[TNS_MAX_ORDER + 1]; for (w = 0; w < ics->num_windows; w++) { bottom = ics->num_swb; @@ -1755,12 +1763,10 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out, } else { memset(in, 0, 448 * sizeof(float)); ac->dsp.vector_fmul(in + 448, in + 448, swindow_prev, 128); - memcpy(in + 576, in + 576, 448 * sizeof(float)); } if (ics->window_sequence[0] != LONG_START_SEQUENCE) { ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024); } else { - memcpy(in + 1024, in + 1024, 448 * sizeof(float)); ac->dsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128); memset(in + 1024 + 576, 0, 448 * sizeof(float)); } @@ -2078,7 +2084,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, ChannelElement *che = NULL, *che_prev = NULL; enum RawDataBlockType elem_type, elem_type_prev = TYPE_END; int err, elem_id, data_size_tmp; - int samples = 0, multiplier; + int samples = 0, multiplier, audio_found = 0; if (show_bits(gb, 12) == 0xfff) { if (parse_adts_frame_header(ac, gb) < 0) { @@ -2109,10 +2115,12 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, case TYPE_SCE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; break; case TYPE_CPE: err = decode_cpe(ac, gb, che); + audio_found = 1; break; case TYPE_CCE: @@ -2121,6 +2129,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, case TYPE_LFE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; break; case TYPE_DSE: @@ -2197,7 +2206,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, samples, avctx->channels); } - if (ac->output_configured) + if (ac->output_configured && audio_found) ac->output_configured = OC_LOCKED; return 0; diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 0de6622389..68fa0aa331 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -153,7 +153,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, avctx->channels); diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index fc124d1972..3cfd18d959 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -813,14 +813,17 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2 const float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; //Remapping - memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0])); - memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0])); - memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0])); - memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0])); - memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0])); - memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0])); - memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0])); - memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0])); + if (ps->num_env_old) { + memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0])); + memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0])); + memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0])); + memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0])); + memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0])); + memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0])); + memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0])); + memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0])); + } + if (is34) { remap34(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); remap34(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 82092b385d..d7a95e86f4 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -33,6 +33,7 @@ #include "fft.h" #include "aacps.h" #include "libavutil/libm.h" +#include "libavutil/avassert.h" #include #include @@ -1182,14 +1183,15 @@ static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct, { int i, n; const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us; + const int step = 128 >> div; float *v; for (i = 0; i < 32; i++) { - if (*v_off == 0) { + if (*v_off < step) { int saved_samples = (1280 - 128) >> div; memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float)); - *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - (128 >> div); + *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step; } else { - *v_off -= 128 >> div; + *v_off -= step; } v = v0 + *v_off; if (div) { @@ -1457,6 +1459,7 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; int k; + av_assert0(sbr->kx[1] <= table[0]); for (i = 0; i < ilim; i++) for (m = table[i]; m < table[i + 1]; m++) sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index a53817e1b0..8e8482f7c5 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -94,7 +94,7 @@ typedef struct AC3BitAllocParameters { * Coded AC-3 header values up to the lfeon element, plus derived values. */ typedef struct { - /** @defgroup coded Coded elements + /** @name Coded elements * @{ */ uint16_t sync_word; @@ -112,7 +112,7 @@ typedef struct { int num_blocks; ///< number of audio blocks /** @} */ - /** @defgroup derived Derived values + /** @name Derived values * @{ */ uint8_t sr_shift; diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 377e5154d7..4b3e7e3d7e 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -69,7 +69,7 @@ typedef struct { AVCodecContext *avctx; ///< parent context GetBitContext gbc; ///< bitstream reader -///@defgroup bsi bit stream information +///@name Bit stream information ///@{ int frame_type; ///< frame type (strmtyp) int substreamid; ///< substream identification @@ -87,7 +87,7 @@ typedef struct { int eac3; ///< indicates if current frame is E-AC-3 ///@} -///@defgroup audfrm frame syntax parameters +///@name Frame syntax parameters int snr_offset_strategy; ///< SNR offset strategy (snroffststr) int block_switch_syntax; ///< block switch syntax enabled (blkswe) int dither_flag_syntax; ///< dither flag syntax enabled (dithflage) @@ -97,7 +97,7 @@ typedef struct { int skip_syntax; ///< skip field syntax enabled (skipflde) ///@} -///@defgroup cpl standard coupling +///@name Standard coupling int cpl_in_use[AC3_MAX_BLOCKS]; ///< coupling in use (cplinu) int cpl_strategy_exists[AC3_MAX_BLOCKS];///< coupling strategy exists (cplstre) int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) @@ -110,7 +110,7 @@ typedef struct { int cpl_coords[AC3_MAX_CHANNELS][AC3_MAX_CPL_BANDS]; ///< coupling coordinates (cplco) ///@} -///@defgroup spx spectral extension +///@name Spectral extension ///@{ int spx_in_use; ///< spectral extension in use (spxinu) uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx) @@ -126,12 +126,12 @@ typedef struct { float spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact) ///@} -///@defgroup aht adaptive hybrid transform +///@name Adaptive hybrid transform int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu) int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][AC3_MAX_BLOCKS]; ///< pre-IDCT mantissas ///@} -///@defgroup channel channel +///@name Channel int fbw_channels; ///< number of full-bandwidth channels int channels; ///< number of total channels int lfe_ch; ///< index of LFE channel @@ -141,27 +141,27 @@ typedef struct { int out_channels; ///< number of output channels ///@} -///@defgroup dynrng dynamic range +///@name Dynamic range float dynamic_range[2]; ///< dynamic range ///@} -///@defgroup bandwidth bandwidth +///@name Bandwidth int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant) int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant) ///@} -///@defgroup rematrixing rematrixing +///@name Rematrixing int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd) int rematrixing_flags[4]; ///< rematrixing flags (rematflg) ///@} -///@defgroup exponents exponents +///@name Exponents int num_exp_groups[AC3_MAX_CHANNELS]; ///< Number of exponent groups (nexpgrp) int8_t dexps[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< decoded exponents int exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS]; ///< exponent strategies (expstr) ///@} -///@defgroup bitalloc bit allocation +///@name Bit allocation AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters int first_cpl_leak; ///< first coupling leak state (firstcplleak) int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets (snroffst) @@ -177,25 +177,25 @@ typedef struct { uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment ///@} -///@defgroup dithering zero-mantissa dithering +///@name Zero-mantissa dithering int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags (dithflg) AVLFG dith_state; ///< for dither generation ///@} -///@defgroup imdct IMDCT +///@name IMDCT int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw) FFTContext imdct_512; ///< for 512 sample IMDCT FFTContext imdct_256; ///< for 256 sample IMDCT ///@} -///@defgroup opt optimization +///@name Optimization DSPContext dsp; ///< for optimization AC3DSPContext ac3dsp; FmtConvertContext fmt_conv; ///< optimized conversion functions float mul_bias; ///< scaling for float_to_int16 conversion ///@} -///@defgroup arrays aligned arrays +///@name Aligned arrays DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients DECLARE_ALIGNED(32, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients DECLARE_ALIGNED(32, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 619addc3d5..675f779b5d 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -108,7 +108,7 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, int snr_offset, int floor, const uint8_t *bap_tab, uint8_t *bap) { - int bin, band; + int bin, band, band_end; /* special case, if snr offset is -960, set all bap's to zero */ if (snr_offset == -960) { @@ -120,12 +120,14 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, band = ff_ac3_bin_to_band_tab[start]; do { int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor; - int band_end = FFMIN(ff_ac3_band_start_tab[band+1], end); + band_end = ff_ac3_band_start_tab[++band]; + band_end = FFMIN(band_end, end); + for (; bin < band_end; bin++) { int address = av_clip((psd[bin] - m) >> 5, 0, 63); bap[bin] = bap_tab[address]; } - } while (end > ff_ac3_band_start_tab[band++]); + } while (end > band_end); } static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap, diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index ba312558b0..6ea600a88f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -778,9 +778,13 @@ static int adpcm_encode_frame(AVCodecContext *avctx, static av_cold int adpcm_decode_init(AVCodecContext * avctx) { ADPCMContext *c = avctx->priv_data; + unsigned int min_channels = 1; unsigned int max_channels = 2; switch(avctx->codec->id) { + case CODEC_ID_ADPCM_EA: + min_channels = 2; + break; case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: @@ -788,8 +792,10 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) max_channels = 6; break; } - if(avctx->channels > max_channels){ - return -1; + + if (avctx->channels < min_channels || avctx->channels > max_channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR(EINVAL); } switch(avctx->codec->id) { @@ -1333,10 +1339,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, buf_size -= 128; } break; - case CODEC_ID_ADPCM_IMA_EA_EACS: + case CODEC_ID_ADPCM_IMA_EA_EACS: { + unsigned header_size = 4 + (8<> (1-st); - if (samples_in_chunk > buf_size-4-(8< buf_size - header_size) { src += buf_size - 4; break; } @@ -1351,6 +1358,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3); } break; + } case CODEC_ID_ADPCM_IMA_EA_SEAD: for (; src < buf+buf_size; src++) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6); @@ -1358,11 +1366,17 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_EA: - if (buf_size < 12 || AV_RL32(src) > (buf_size - 12)/30*28) { - src += buf_size; - break; + /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces, + each coding 28 stereo samples. */ + if (buf_size < 12) { + av_log(avctx, AV_LOG_ERROR, "frame too small\n"); + return AVERROR(EINVAL); } samples_in_chunk = AV_RL32(src); + if (samples_in_chunk / 28 > (buf_size - 12) / 30) { + av_log(avctx, AV_LOG_ERROR, "invalid frame\n"); + return AVERROR(EINVAL); + } src += 4; current_left_sample = (int16_t)bytestream_get_le16(&src); previous_left_sample = (int16_t)bytestream_get_le16(&src); diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 96c15fffc9..6e7a0ed5be 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -664,10 +664,9 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) alac->numchannels = alac->avctx->channels; /* initialize from the extradata */ - if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) { - av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n", - ALAC_EXTRADATA_SIZE); - return -1; + if (alac->avctx->extradata_size < ALAC_EXTRADATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "alac: extradata is too small\n"); + return AVERROR_INVALIDDATA; } if (alac_set_info(alac)) { av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n"); diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index bb618e16f2..235bff6637 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -257,7 +257,7 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) // generate warm-up samples residual[0] = samples[0]; for(i=1;i<=lpc.lpc_order;i++) - residual[i] = samples[i] - samples[i-1]; + residual[i] = sign_extend(samples[i] - samples[i-1], s->write_sample_size); // perform lpc on remaining samples for(i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) { diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index e6305cf7d2..c038524f75 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -370,6 +370,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (XSUB, xsub); /* external libraries */ + REGISTER_ENCODER (LIBAACPLUS, libaacplus); REGISTER_DECODER (LIBCELT, libcelt); REGISTER_ENCDEC (LIBDIRAC, libdirac); REGISTER_ENCODER (LIBFAAC, libfaac); @@ -380,7 +381,7 @@ void avcodec_register_all(void) REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); REGISTER_DECODER (LIBOPENJPEG, libopenjpeg); REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); - REGISTER_DECODER (LIBSPEEX, libspeex); + REGISTER_ENCDEC (LIBSPEEX, libspeex); REGISTER_ENCODER (LIBTHEORA, libtheora); REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc); REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc); diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 509d49c694..8cb5a6089c 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -551,12 +551,15 @@ static void get_block_sizes(ALSDecContext *ctx, unsigned int *div_blocks, /** Read the block data for a constant block */ -static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) +static int read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) { ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; GetBitContext *gb = &ctx->gb; + if (bd->block_length <= 0) + return -1; + *bd->raw_samples = 0; *bd->const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence) bd->js_blocks = get_bits1(gb); @@ -571,6 +574,8 @@ static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) // ensure constant block decoding by reusing this field *bd->const_block = 1; + + return 0; } @@ -650,6 +655,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) for (k = 1; k < sub_blocks; k++) s[k] = s[k - 1] + decode_rice(gb, 0); } + for (k = 1; k < sub_blocks; k++) + if (s[k] > 32) { + av_log(avctx, AV_LOG_ERROR, "k invalid for rice code.\n"); + return AVERROR_INVALIDDATA; + } if (get_bits1(gb)) *bd->shift_lsbs = get_bits(gb, 4) + 1; @@ -662,6 +672,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1, 2, sconf->max_order + 1)); *bd->opt_order = get_bits(gb, opt_order_length); + if (*bd->opt_order > sconf->max_order) { + *bd->opt_order = sconf->max_order; + av_log(avctx, AV_LOG_ERROR, "Predictor order too large!\n"); + return AVERROR_INVALIDDATA; + } } else { *bd->opt_order = sconf->max_order; } @@ -694,6 +709,10 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) int rice_param = parcor_rice_table[sconf->coef_table][k][1]; int offset = parcor_rice_table[sconf->coef_table][k][0]; quant_cof[k] = decode_rice(gb, rice_param) + offset; + if (quant_cof[k] < -64 || quant_cof[k] > 63) { + av_log(avctx, AV_LOG_ERROR, "quant_cof %d is out of range\n", quant_cof[k]); + return AVERROR_INVALIDDATA; + } } // read coefficients 20 to 126 @@ -726,7 +745,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) bd->ltp_gain[0] = decode_rice(gb, 1) << 3; bd->ltp_gain[1] = decode_rice(gb, 2) << 3; - r = get_unary(gb, 0, 4); + r = get_unary(gb, 0, 3); c = get_bits(gb, 2); bd->ltp_gain[2] = ltp_gain_values[r][c]; @@ -755,7 +774,6 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) int delta[8]; unsigned int k [8]; unsigned int b = av_clip((av_ceil_log2(bd->block_length) - 3) >> 1, 0, 5); - unsigned int i = start; // read most significant bits unsigned int high; @@ -766,29 +784,30 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) current_res = bd->raw_samples + start; - for (sb = 0; sb < sub_blocks; sb++, i = 0) { + for (sb = 0; sb < sub_blocks; sb++) { + unsigned int sb_len = sb_length - (sb ? 0 : start); + k [sb] = s[sb] > b ? s[sb] - b : 0; delta[sb] = 5 - s[sb] + k[sb]; - ff_bgmc_decode(gb, sb_length, current_res, + ff_bgmc_decode(gb, sb_len, current_res, delta[sb], sx[sb], &high, &low, &value, ctx->bgmc_lut, ctx->bgmc_lut_status); - current_res += sb_length; + current_res += sb_len; } ff_bgmc_decode_end(gb); // read least significant bits and tails - i = start; current_res = bd->raw_samples + start; - for (sb = 0; sb < sub_blocks; sb++, i = 0) { + for (sb = 0; sb < sub_blocks; sb++, start = 0) { unsigned int cur_tail_code = tail_code[sx[sb]][delta[sb]]; unsigned int cur_k = k[sb]; unsigned int cur_s = s[sb]; - for (; i < sb_length; i++) { + for (; start < sb_length; start++) { int32_t res = *current_res; if (res == cur_tail_code) { @@ -956,7 +975,8 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) if (read_var_block_data(ctx, bd)) return -1; } else { - read_const_block_data(ctx, bd); + if (read_const_block_data(ctx, bd) < 0) + return -1; } return 0; @@ -1010,7 +1030,7 @@ static void zero_remaining(unsigned int b, unsigned int b_max, { unsigned int count = 0; - while (b < b_max) + for (; b < b_max; b++) count += div_blocks[b]; if (count) diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index 55dc8b05f5..96412bfc21 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -204,7 +204,7 @@ static enum Mode unpack_bitstream(AMRContext *p, const uint8_t *buf, } -/// @defgroup amr_lpc_decoding AMR pitch LPC coefficient decoding functions +/// @name AMR pitch LPC coefficient decoding functions /// @{ /** @@ -341,7 +341,7 @@ static void lsf2lsp_3(AMRContext *p) /// @} -/// @defgroup amr_pitch_vector_decoding AMR pitch vector decoding functions +/// @name AMR pitch vector decoding functions /// @{ /** @@ -403,7 +403,7 @@ static void decode_pitch_vector(AMRContext *p, /// @} -/// @defgroup amr_algebraic_code_book AMR algebraic code book (fixed) vector decoding functions +/// @name AMR algebraic code book (fixed) vector decoding functions /// @{ /** @@ -547,7 +547,7 @@ static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode, /// @} -/// @defgroup amr_gain_decoding AMR gain decoding functions +/// @name AMR gain decoding functions /// @{ /** @@ -633,7 +633,7 @@ static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe, /// @} -/// @defgroup amr_pre_processing AMR pre-processing functions +/// @name AMR preprocessing functions /// @{ /** @@ -751,7 +751,7 @@ static const float *anti_sparseness(AMRContext *p, AMRFixed *fixed_sparse, /// @} -/// @defgroup amr_synthesis AMR synthesis functions +/// @name AMR synthesis functions /// @{ /** @@ -812,7 +812,7 @@ static int synthesis(AMRContext *p, float *lpc, /// @} -/// @defgroup amr_update AMR update functions +/// @name AMR update functions /// @{ /** @@ -837,7 +837,7 @@ static void update_state(AMRContext *p) /// @} -/// @defgroup amr_postproc AMR Post processing functions +/// @name AMR Postprocessing functions /// @{ /** diff --git a/libavcodec/anm.c b/libavcodec/anm.c index 02244f70e1..8e40059576 100644 --- a/libavcodec/anm.c +++ b/libavcodec/anm.c @@ -79,6 +79,8 @@ static inline int op(uint8_t **dst, const uint8_t *dst_end, int striplen = FFMIN(count, remaining); if (buf) { striplen = FFMIN(striplen, buf_end - *buf); + if (*buf >= buf_end) + goto exhausted; memcpy(*dst, *buf, striplen); *buf += striplen; } else if (pixel >= 0) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 05498777b4..4d8a9401c1 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -163,6 +163,18 @@ typedef struct APEContext { // TODO: dsputilize +static av_cold int ape_decode_close(AVCodecContext * avctx) +{ + APEContext *s = avctx->priv_data; + int i; + + for (i = 0; i < APE_FILTER_LEVELS; i++) + av_freep(&s->filterbuf[i]); + + av_freep(&s->data); + return 0; +} + static av_cold int ape_decode_init(AVCodecContext * avctx) { APEContext *s = avctx->priv_data; @@ -195,29 +207,22 @@ static av_cold int ape_decode_init(AVCodecContext * avctx) for (i = 0; i < APE_FILTER_LEVELS; i++) { if (!ape_filter_orders[s->fset][i]) break; - s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4); + FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i], + (ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4, + filter_alloc_fail); } dsputil_init(&s->dsp, avctx); avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; return 0; -} - -static av_cold int ape_decode_close(AVCodecContext * avctx) -{ - APEContext *s = avctx->priv_data; - int i; - - for (i = 0; i < APE_FILTER_LEVELS; i++) - av_freep(&s->filterbuf[i]); - - av_freep(&s->data); - return 0; +filter_alloc_fail: + ape_decode_close(avctx); + return AVERROR(ENOMEM); } /** - * @defgroup rangecoder APE range decoder + * @name APE range decoding functions * @{ */ @@ -797,7 +802,7 @@ static int ape_decode_frame(AVCodecContext * avctx, int buf_size = avpkt->size; APEContext *s = avctx->priv_data; int16_t *samples = data; - int nblocks; + uint32_t nblocks; int i, n; int blockstodecode; int bytes_used; @@ -814,12 +819,15 @@ static int ape_decode_frame(AVCodecContext * avctx, } if(!s->samples){ - s->data = av_realloc(s->data, (buf_size + 3) & ~3); + void *tmp_data = av_realloc(s->data, (buf_size + 3) & ~3); + if (!tmp_data) + return AVERROR(ENOMEM); + s->data = tmp_data; s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); s->ptr = s->last_ptr = s->data; s->data_end = s->data + buf_size; - nblocks = s->samples = bytestream_get_be32(&s->ptr); + nblocks = bytestream_get_be32(&s->ptr); n = bytestream_get_be32(&s->ptr); if(n < 0 || n > 3){ av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); @@ -828,12 +836,13 @@ static int ape_decode_frame(AVCodecContext * avctx, } s->ptr += n; - s->currentframeblocks = nblocks; buf += 4; - if (s->samples <= 0) { + if (!nblocks || nblocks > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); *data_size = 0; - return buf_size; + return AVERROR_INVALIDDATA; } + s->currentframeblocks = s->samples = nblocks; memset(s->decoded0, 0, sizeof(s->decoded0)); memset(s->decoded1, 0, sizeof(s->decoded1)); diff --git a/libavcodec/arm/fft_fixed_neon.S b/libavcodec/arm/fft_fixed_neon.S index bd6c853ec8..4e4b94a8e3 100644 --- a/libavcodec/arm/fft_fixed_neon.S +++ b/libavcodec/arm/fft_fixed_neon.S @@ -56,7 +56,7 @@ vhsub.s16 \r0, \d0, \d1 @ t3, t4, t8, t7 vhsub.s16 \r1, \d1, \d0 vhadd.s16 \d0, \d0, \d1 @ t1, t2, t6, t5 - vmov.i64 \d1, #0xffff<<32 + vmov.i64 \d1, #0xffff00000000 vbit \r0, \r1, \d1 vrev64.16 \r1, \r0 @ t7, t8, t4, t3 vtrn.32 \r0, \r1 @ t3, t4, t7, t8 diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S index e8023e0686..f86bf53f95 100644 --- a/libavcodec/arm/int_neon.S +++ b/libavcodec/arm/int_neon.S @@ -67,10 +67,10 @@ function ff_scalarproduct_int16_neon, export=1 3: vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] @@ -107,10 +107,10 @@ function ff_scalarproduct_and_madd_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] diff --git a/libavcodec/ass.h b/libavcodec/ass.h index 74ef61b776..efff44d6ed 100644 --- a/libavcodec/ass.h +++ b/libavcodec/ass.h @@ -25,8 +25,7 @@ #include "avcodec.h" /** - * Default values for ASS style. - * @defgroup ass_default + * @name Default values for ASS style * @{ */ #define ASS_DEFAULT_FONT "Arial" diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c index 2a3b76445e..33c1c2714f 100644 --- a/libavcodec/ass_split.c +++ b/libavcodec/ass_split.c @@ -366,7 +366,7 @@ int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, char new_line[2]; int text_len = 0; - while (*buf) { + while (buf && *buf) { if (text && callbacks->text && (sscanf(buf, "\\%1[nN]", new_line) == 1 || !strncmp(buf, "{\\", 2))) { diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 1f4c36c141..6897790307 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -276,7 +276,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AT1Ctx *q = avctx->priv_data; - int ch, ret, i; + int ch, ret, i, out_size; GetBitContext gb; float* samples = data; @@ -286,6 +286,13 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, return -1; } + out_size = q->channels * AT1_SU_SAMPLES * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + for (ch = 0; ch < q->channels; ch++) { AT1SUCtx* su = &q->SUs[ch]; @@ -318,7 +325,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, } } - *data_size = q->channels * AT1_SU_SAMPLES * sizeof(*samples); + *data_size = out_size; return avctx->block_align; } @@ -329,6 +336,11 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + if (avctx->channels < 1 || avctx->channels > AT1_MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", + avctx->channels); + return AVERROR(EINVAL); + } q->channels = avctx->channels; /* Init the mdct transforms */ diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 20ab75dfd7..dc1a7e0972 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -179,8 +179,11 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ uint32_t* obuf = (uint32_t*) out; off = (intptr_t)inbuffer & 3; - buf = (const uint32_t*) (inbuffer - off); - c = av_be2ne32((0x537F6103 >> (off*8)) | (0x537F6103 << (32-(off*8)))); + buf = (const uint32_t *)(inbuffer - off); + if (off) + c = av_be2ne32((0x537F6103U >> (off * 8)) | (0x537F6103U << (32 - (off * 8)))); + else + c = av_be2ne32(0x537F6103U); bytes += 3 + off; for (i = 0; i < bytes/4; i++) obuf[i] = c ^ buf[i]; @@ -395,6 +398,8 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent for (k=0; k= 64) + return AVERROR_INVALIDDATA; pComponent[component_count].pos = j * 64 + (get_bits(gb,6)); max_coded_values = 1024 - pComponent[component_count].pos; coded_values = coded_values_per_component + 1; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 90c389b8c5..10c628862c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -30,9 +30,16 @@ #include "libavutil/samplefmt.h" #include "libavutil/avutil.h" #include "libavutil/cpu.h" +#include "libavutil/dict.h" #include "libavcodec/version.h" +#if LIBAVCODEC_VERSION_MAJOR < 53 +# define FF_INTERNALC_MEM_TYPE unsigned int +#else +# define FF_INTERNALC_MEM_TYPE size_t +#endif + /** * Identify the syntax and semantics of the bitstream. * The principle is roughly: @@ -111,6 +118,9 @@ enum CodecID { CODEC_ID_QDRAW, CODEC_ID_VIXL, CODEC_ID_QPEG, +#if LIBAVCODEC_VERSION_MAJOR < 53 + CODEC_ID_XVID, +#endif CODEC_ID_PNG, CODEC_ID_PPM, CODEC_ID_PBM, @@ -359,6 +369,18 @@ enum CodecID { CODEC_ID_FFMETADATA=0x21000, ///< Dummy codec for streams containing only metadata information. }; +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define CodecType AVMediaType + +#define CODEC_TYPE_UNKNOWN AVMEDIA_TYPE_UNKNOWN +#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO +#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO +#define CODEC_TYPE_DATA AVMEDIA_TYPE_DATA +#define CODEC_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE +#define CODEC_TYPE_ATTACHMENT AVMEDIA_TYPE_ATTACHMENT +#define CODEC_TYPE_NB AVMEDIA_TYPE_NB +#endif + #if FF_API_OLD_SAMPLE_FMT #define SampleFormat AVSampleFormat @@ -522,7 +544,7 @@ enum AVChromaLocation{ /** * LPC analysis type */ -attribute_deprecated enum AVLPCType { +enum AVLPCType { AV_LPC_TYPE_DEFAULT = -1, ///< use the codec default LPC type AV_LPC_TYPE_NONE = 0, ///< do not use LPC prediction or use all zero coefficients AV_LPC_TYPE_FIXED = 1, ///< fixed LPC coefficients @@ -1070,10 +1092,6 @@ typedef struct AVPanScan{ #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). -enum AVPacketSideDataType { - AV_PKT_DATA_PALETTE, -}; - typedef struct AVPacket { /** * Presentation timestamp in AVStream->time_base units; the time at which @@ -1095,17 +1113,6 @@ typedef struct AVPacket { int size; int stream_index; int flags; - /** - * Additional packet data that can be provided by the container. - * Packet can contain several types of side information. - */ - struct { - uint8_t *data; - int size; - enum AVPacketSideDataType type; - } *side_data; - int side_data_elems; - /** * Duration of this packet in AVStream->time_base units, 0 if unknown. * Equals next_pts - this_pts in presentation order. @@ -1135,6 +1142,9 @@ typedef struct AVPacket { int64_t convergence_duration; } AVPacket; #define AV_PKT_FLAG_KEY 0x0001 +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif /** * Audio Video Frame. @@ -1255,6 +1265,16 @@ typedef struct AVCodecContext { */ enum PixelFormat pix_fmt; +#if FF_API_RATE_EMU + /** + * Frame rate emulation. If not zero, the lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: Set by user. + * - decoding: unused + */ + attribute_deprecated int rate_emu; +#endif + /** * If non NULL, 'draw_horiz_band' is called by the libavcodec * decoder to draw a horizontal band. It improves cache usage. Not @@ -1299,6 +1319,9 @@ typedef struct AVCodecContext { */ int frame_size; int frame_number; ///< audio or video frame number +#if LIBAVCODEC_VERSION_MAJOR < 53 + int real_pict_num; ///< Returns the real picture number of previous encoded frame. +#endif /** * Number of frames the decoded output will be delayed relative to @@ -1356,6 +1379,16 @@ typedef struct AVCodecContext { int b_frame_strategy; +#if FF_API_HURRY_UP + /** + * hurry up amount + * - encoding: unused + * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header + * @deprecated Deprecated in favor of skip_idct and skip_frame. + */ + attribute_deprecated int hurry_up; +#endif + struct AVCodec *codec; void *priv_data; @@ -1473,6 +1506,9 @@ typedef struct AVCodecContext { #define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software. #define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. #define FF_COMPLIANCE_NORMAL 0 +#if FF_API_INOFFICIAL +#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions (deprecated - use FF_COMPLIANCE_UNOFFICIAL instead). +#endif #define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions #define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. @@ -1746,6 +1782,25 @@ typedef struct AVCodecContext { */ unsigned dsp_mask; +#if FF_API_MM_FLAGS +#define FF_MM_FORCE AV_CPU_FLAG_FORCE +#define FF_MM_MMX AV_CPU_FLAG_MMX +#define FF_MM_3DNOW AV_CPU_FLAG_3DNOW +#define FF_MM_MMXEXT AV_CPU_FLAG_MMX2 +#define FF_MM_MMX2 AV_CPU_FLAG_MMX2 +#define FF_MM_SSE AV_CPU_FLAG_SSE +#define FF_MM_SSE2 AV_CPU_FLAG_SSE2 +#define FF_MM_SSE2SLOW AV_CPU_FLAG_SSE2SLOW +#define FF_MM_3DNOWEXT AV_CPU_FLAG_3DNOWEXT +#define FF_MM_SSE3 AV_CPU_FLAG_SSE3 +#define FF_MM_SSE3SLOW AV_CPU_FLAG_SSE3SLOW +#define FF_MM_SSSE3 AV_CPU_FLAG_SSSE3 +#define FF_MM_SSE4 AV_CPU_FLAG_SSE4 +#define FF_MM_SSE42 AV_CPU_FLAG_SSE42 +#define FF_MM_IWMMXT AV_CPU_FLAG_IWMMXT +#define FF_MM_ALTIVEC AV_CPU_FLAG_ALTIVEC +#endif + /** * bits per sample/pixel from the demuxer (needed for huffyuv). * - encoding: Set by libavcodec. @@ -1820,6 +1875,22 @@ typedef struct AVCodecContext { */ uint64_t error[4]; +#if FF_API_MB_Q + /** + * minimum MB quantizer + * - encoding: unused + * - decoding: unused + */ + attribute_deprecated int mb_qmin; + + /** + * maximum MB quantizer + * - encoding: unused + * - decoding: unused + */ + attribute_deprecated int mb_qmax; +#endif + /** * motion estimation comparison function * - encoding: Set by user. @@ -2521,6 +2592,23 @@ typedef struct AVCodecContext { int compression_level; #define FF_COMPRESSION_DEFAULT -1 +#if FF_API_USE_LPC + /** + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused + * @deprecated Deprecated in favor of lpc_type and lpc_passes. + */ + int use_lpc; + + /** + * LPC coefficient precision - used by FLAC encoder + * - encoding: Set by user. + * - decoding: unused + */ + int lpc_coeff_precision; +#endif + /** * - encoding: Set by user. * - decoding: unused @@ -2535,18 +2623,11 @@ typedef struct AVCodecContext { #if FF_API_FLAC_GLOBAL_OPTS /** - * @defgroup flac_opts FLAC options + * @name FLAC options * @deprecated Use FLAC encoder private options instead. * @{ */ - /** - * LPC coefficient precision - used by FLAC encoder - * - encoding: Set by user. - * - decoding: unused - */ - attribute_deprecated int lpc_coeff_precision; - /** * search method for selecting prediction order * - encoding: Set by user. @@ -2606,7 +2687,6 @@ typedef struct AVCodecContext { /** * Bits per sample/pixel of internal libavcodec pixel/sample format. - * This field is applicable only when sample_fmt is AV_SAMPLE_FMT_S32. * - encoding: set by user. * - decoding: set by libavcodec. */ @@ -2957,7 +3037,7 @@ typedef struct AVCodec { const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} /** - * @defgroup framethreading Frame-level threading support functions. + * @name Frame-level threading support functions * @{ */ /** @@ -3211,33 +3291,6 @@ int av_dup_packet(AVPacket *pkt); */ void av_free_packet(AVPacket *pkt); -/** - * Allocate new information of a packet. - * - * @param pkt packet - * @param type side information type - * @param size side information size - * @return pointer to fresh allocated data or NULL otherwise - */ -uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - int size); - -/** - * Get side information from packet. - * - * @param pkt packet - * @param type desired side information type - * @param size pointer for side information size to store (optional) - * @return pointer to data if present or NULL otherwise - */ -uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - int *size); - -int av_packet_merge_side_data(AVPacket *pkt); - -int av_packet_split_side_data(AVPacket *pkt); - - /* resample.c */ struct ReSampleContext; @@ -3245,6 +3298,14 @@ struct AVResampleContext; typedef struct ReSampleContext ReSampleContext; +#if FF_API_AUDIO_OLD +/** + * @deprecated Use av_audio_resample_init() instead. + */ +attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +#endif + /** * Initialize audio resampling context. * @@ -3408,6 +3469,23 @@ const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt); void avcodec_set_dimensions(AVCodecContext *s, int width, int height); +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Return the pixel format corresponding to the name name. + * + * If there is no pixel format with name name, then look for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first look for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, return PIX_FMT_NONE. + * + * @deprecated Deprecated in favor of av_get_pix_fmt(). + */ +attribute_deprecated enum PixelFormat avcodec_get_pix_fmt(const char* name); +#endif + /** * Return a value representing the fourCC code associated to the * pixel format pix_fmt, or 0 if no associated fourCC code can be @@ -3476,6 +3554,14 @@ int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_ enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Use av_get_pix_fmt_string() instead. + */ +attribute_deprecated +void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt); +#endif + #define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ #define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ @@ -3526,6 +3612,13 @@ const char *avcodec_license(void); */ void avcodec_init(void); +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Deprecated in favor of avcodec_register(). + */ +attribute_deprecated void register_avcodec(AVCodec *codec); +#endif + /** * Register the codec codec and initialize libavcodec. * @@ -3670,6 +3763,14 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]); +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Deprecated in favor of av_check_image_size(). + */ +attribute_deprecated +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h); +#endif + enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt); #if FF_API_THREAD_INIT @@ -3678,12 +3779,13 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum */ attribute_deprecated int avcodec_thread_init(AVCodecContext *s, int thread_count); +void avcodec_thread_free(AVCodecContext *s); #endif - int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); //FIXME func typedef +#if FF_API_AVCODEC_OPEN /** * Initialize the AVCodecContext to use the given AVCodec. Prior to using this * function the context has to be allocated. @@ -3710,8 +3812,63 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, * @param codec The codec to use within the context. * @return zero on success, a negative value on error * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder, avcodec_close + * + * @deprecated use avcodec_open2 */ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); +#endif + +/** + * Initialize the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated with avcodec_alloc_context(). + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * av_dict_set(&opts, "b", "2.5M", 0); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context(); + * + * if (avcodec_open(context, codec, opts) < 0) + * exit(1); + * @endcode + * + * @param avctx The context to initialize. + * @param options A dictionary filled with AVCodecContext and codec-private options. + * On return this object will be filled with options that were not found. + * + * @return zero on success, a negative value on error + * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(), + * av_dict_set(), av_opt_find(). + */ +int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options); + +#if FF_API_AUDIO_OLD +/** + * Decode an audio frame from buf into samples. + * Wrapper function which calls avcodec_decode_audio3. + * + * @deprecated Use avcodec_decode_audio3 instead. + * @param avctx the codec context + * @param[out] samples the output buffer + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] buf the input buffer + * @param[in] buf_size the input buffer size in bytes + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size); +#endif /** * Decode the audio frame of size avpkt->size from avpkt->data into samples. @@ -3756,6 +3913,25 @@ int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, AVPacket *avpkt); +#if FF_API_VIDEO_OLD +/** + * Decode a video frame from buf into picture. + * Wrapper function which calls avcodec_decode_video2. + * + * @deprecated Use avcodec_decode_video2 instead. + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * @param[in] buf the input buffer + * @param[in] buf_size the size of the input buffer in bytes + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size); +#endif + /** * Decode the video frame of size avpkt->size from avpkt->data into picture. * Some decoders may support multiple frames in a single AVPacket, such @@ -3800,6 +3976,15 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt); +#if FF_API_SUBTITLE_OLD +/* Decode a subtitle message. Return -1 if error, otherwise return the + * number of bytes used. If no subtitle could be decompressed, + * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ +attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size); +#endif + /** * Decode a subtitle message. * Return a negative value on error, otherwise return the number of bytes used. @@ -3915,7 +4100,7 @@ int av_get_bits_per_sample(enum CodecID codec_id); #if FF_API_OLD_SAMPLE_FMT /** - * @deprecated Use av_get_bits_per_sample_fmt() instead. + * @deprecated Use av_get_bytes_per_sample() instead. */ attribute_deprecated int av_get_bits_per_sample_format(enum AVSampleFormat sample_fmt); @@ -4068,6 +4253,15 @@ AVCodecParser *av_parser_next(AVCodecParser *c); void av_register_codec_parser(AVCodecParser *parser); AVCodecParserContext *av_parser_init(int codec_id); +#if LIBAVCODEC_VERSION_MAJOR < 53 +attribute_deprecated +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); +#endif + /** * Parse a packet. * @@ -4146,7 +4340,7 @@ AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); * * @see av_realloc */ -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); +void *av_fast_realloc(void *ptr, unsigned int *size, FF_INTERNALC_MEM_TYPE min_size); /** * Allocate a buffer, reusing the given one if large enough. @@ -4160,7 +4354,17 @@ void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and * *size 0 if an error occurred. */ -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); +void av_fast_malloc(void *ptr, unsigned int *size, FF_INTERNALC_MEM_TYPE min_size); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Deprecated in favor of av_image_copy(). + */ +attribute_deprecated +void av_picture_data_copy(uint8_t *dst_data[4], int dst_linesize[4], + uint8_t *src_data[4], int src_linesize[4], + enum PixelFormat pix_fmt, int width, int height); +#endif /** * Copy image src to dst. Wraps av_picture_data_copy() above. @@ -4189,6 +4393,22 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, */ unsigned int av_xiphlacing(unsigned char *s, unsigned int v); +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Parse str and put in width_ptr and height_ptr the detected values. + * + * @deprecated Deprecated in favor of av_parse_video_size(). + */ +attribute_deprecated int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parse str and store the detected values in *frame_rate. + * + * @deprecated Deprecated in favor of av_parse_video_rate(). + */ +attribute_deprecated int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); +#endif + /** * Logs a generic warning message about a missing feature. This function is * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index ff34285b48..5825854987 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -26,21 +26,12 @@ void av_destruct_packet_nofree(AVPacket *pkt) { pkt->data = NULL; pkt->size = 0; - pkt->side_data = NULL; - pkt->side_data_elems = 0; } void av_destruct_packet(AVPacket *pkt) { - int i; - av_free(pkt->data); pkt->data = NULL; pkt->size = 0; - - for (i = 0; i < pkt->side_data_elems; i++) - av_free(pkt->side_data[i].data); - av_freep(&pkt->side_data); - pkt->side_data_elems = 0; } void av_init_packet(AVPacket *pkt) @@ -53,8 +44,6 @@ void av_init_packet(AVPacket *pkt) pkt->flags = 0; pkt->stream_index = 0; pkt->destruct= NULL; - pkt->side_data = NULL; - pkt->side_data_elems = 0; } int av_new_packet(AVPacket *pkt, int size) @@ -100,52 +89,23 @@ int av_grow_packet(AVPacket *pkt, int grow_by) return 0; } -#define DUP_DATA(dst, src, size, padding) \ - do { \ - void *data; \ - if (padding) { \ - if ((unsigned)(size) > (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \ - goto failed_alloc; \ - data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \ - } else { \ - data = av_malloc(size); \ - } \ - if (!data) \ - goto failed_alloc; \ - memcpy(data, src, size); \ - if (padding) \ - memset((uint8_t*)data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); \ - dst = data; \ - } while(0) - int av_dup_packet(AVPacket *pkt) { - AVPacket tmp_pkt; - if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) { - tmp_pkt = *pkt; - - pkt->data = NULL; - pkt->side_data = NULL; - DUP_DATA(pkt->data, tmp_pkt.data, pkt->size, 1); - pkt->destruct = av_destruct_packet; - - if (pkt->side_data_elems) { - int i; - - DUP_DATA(pkt->side_data, tmp_pkt.side_data, - pkt->side_data_elems * sizeof(*pkt->side_data), 0); - memset(pkt->side_data, 0, pkt->side_data_elems * sizeof(*pkt->side_data)); - for (i = 0; i < pkt->side_data_elems; i++) { - DUP_DATA(pkt->side_data[i].data, tmp_pkt.side_data[i].data, - pkt->side_data[i].size, 1); - } + uint8_t *data; + /* We duplicate the packet and don't forget to add the padding again. */ + if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(ENOMEM); + data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!data) { + return AVERROR(ENOMEM); } + memcpy(data, pkt->data, pkt->size); + memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + pkt->data = data; + pkt->destruct = av_destruct_packet; } return 0; -failed_alloc: - av_destruct_packet(pkt); - return AVERROR(ENOMEM); } void av_free_packet(AVPacket *pkt) @@ -153,125 +113,6 @@ void av_free_packet(AVPacket *pkt) if (pkt) { if (pkt->destruct) pkt->destruct(pkt); pkt->data = NULL; pkt->size = 0; - pkt->side_data = NULL; - pkt->side_data_elems = 0; } } -uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - int size) -{ - int elems = pkt->side_data_elems; - - if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data)) - return NULL; - if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) - return NULL; - - pkt->side_data = av_realloc(pkt->side_data, (elems + 1) * sizeof(*pkt->side_data)); - if (!pkt->side_data) - return NULL; - - pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!pkt->side_data[elems].data) - return NULL; - pkt->side_data[elems].size = size; - pkt->side_data[elems].type = type; - pkt->side_data_elems++; - - return pkt->side_data[elems].data; -} - -uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - int *size) -{ - int i; - - for (i = 0; i < pkt->side_data_elems; i++) { - if (pkt->side_data[i].type == type) { - if (size) - *size = pkt->side_data[i].size; - return pkt->side_data[i].data; - } - } - return NULL; -} - -#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL - -int av_packet_merge_side_data(AVPacket *pkt){ - if(pkt->side_data_elems){ - int i; - uint8_t *p; - uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE; - AVPacket old= *pkt; - for (i=0; i INT_MAX) - return AVERROR(EINVAL); - p = av_malloc(size); - if (!p) - return AVERROR(ENOMEM); - pkt->data = p; - pkt->destruct = av_destruct_packet; - pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE; - bytestream_put_buffer(&p, old.data, old.size); - for (i=old.side_data_elems-1; i>=0; i--) { - bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size); - bytestream_put_be32(&p, old.side_data[i].size); - *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128); - } - bytestream_put_be64(&p, FF_MERGE_MARKER); - av_assert0(p-pkt->data == pkt->size); - memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE); - av_free_packet(&old); - pkt->side_data_elems = 0; - pkt->side_data = NULL; - return 1; - } - return 0; -} - -int av_packet_split_side_data(AVPacket *pkt){ - if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){ - int i; - unsigned int size; - uint8_t *p= pkt->data + pkt->size - 8 - 5; - - av_dup_packet(pkt); - - for (i=1; ; i++){ - size = AV_RB32(p); - if (size>INT_MAX || p - pkt->data <= size) - return 0; - if (p[4]&128) - break; - p-= size+5; - } - - pkt->side_data = av_malloc(i * sizeof(*pkt->side_data)); - if (!pkt->side_data) - return AVERROR(ENOMEM); - - p= pkt->data + pkt->size - 8 - 5; - 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].size = size; - pkt->side_data[i].type = p[4]&127; - if (!pkt->side_data[i].data) - return AVERROR(ENOMEM); - memcpy(pkt->side_data[i].data, p-size, size); - pkt->size -= size + 5; - if(p[4]&128) - break; - p-= size+5; - } - pkt->size -= 8; - pkt->side_data_elems = i+1; - return 1; - } - return 0; -} diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 06fcd5cd0e..403398ea62 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -47,6 +47,7 @@ avs_decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; @@ -69,6 +70,8 @@ avs_decode_frame(AVCodecContext * avctx, out = avs->picture.data[0]; stride = avs->picture.linesize[0]; + if (buf_end - buf < 4) + return AVERROR_INVALIDDATA; sub_type = buf[0]; type = buf[1]; buf += 4; @@ -79,6 +82,8 @@ avs_decode_frame(AVCodecContext * avctx, first = AV_RL16(buf); last = first + AV_RL16(buf + 2); + if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first)) + return AVERROR_INVALIDDATA; buf += 4; for (i=first; ipriv_data; avctx->pix_fmt = PIX_FMT_PAL8; avcodec_get_frame_defaults(&avs->picture); + avcodec_set_dimensions(avctx, 318, 198); return 0; } diff --git a/libavcodec/bink.c b/libavcodec/bink.c index ef07747dbc..1508173a5d 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -246,7 +246,7 @@ static void read_tree(GetBitContext *gb, Tree *tree) tree->syms[i] = get_bits(gb, 4); tmp1[tree->syms[i]] = 1; } - for (i = 0; i < 16; i++) + for (i = 0; i < 16 && len < 16 - 1; i++) if (!tmp1[i]) tree->syms[++len] = i; } else { @@ -343,14 +343,14 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle * memset(b->cur_dec, v, t); b->cur_dec += t; } else { - do { + while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } *b->cur_dec++ = v; - } while (b->cur_dec < dec_end); + } } return 0; } @@ -374,7 +374,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) memset(b->cur_dec, v, t); b->cur_dec += t; } else { - do { + while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v < 12) { last = v; @@ -382,10 +382,12 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) } else { int run = bink_rlelens[v - 12]; + if (dec_end - b->cur_dec < run) + return -1; memset(b->cur_dec, last, run); b->cur_dec += run; } - } while (b->cur_dec < dec_end); + } } return 0; } @@ -455,7 +457,8 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, int start_bits, int has_sign) { int i, j, len, len2, bsize, sign, v, v2; - int16_t *dst = (int16_t*)b->cur_dec; + int16_t *dst = (int16_t*)b->cur_dec; + int16_t *dst_end = (int16_t*)b->data_end; CHECK_READ_VAL(gb, b, len); v = get_bits(gb, start_bits - has_sign); @@ -463,10 +466,14 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, sign = -get_bits1(gb); v = (v ^ sign) - sign; } + if (dst_end - dst < 1) + return -1; *dst++ = v; len--; for (i = 0; i < len; i += 8) { len2 = FFMIN(len - i, 8); + if (dst_end - dst < len2) + return -1; bsize = get_bits(gb, 4); if (bsize) { for (j = 0; j < len2; j++) { @@ -534,6 +541,8 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) int i, len; CHECK_READ_VAL(gb, b, len); + if (b->data_end - b->cur_dec < len * (1 + (bits > 8))) + return -1; if (bits <= 8) { if (!issigned) { for (i = 0; i < len; i++) @@ -571,6 +580,22 @@ static inline int binkb_get_value(BinkContext *c, int bundle_num) return ret; } +static inline DCTELEM dequant(DCTELEM in, uint32_t quant, int dc) +{ + /* Note: multiplication is unsigned but we want signed shift + * otherwise clipping breaks. + * TODO: The official decoder does not use clipping at all + * but instead uses the full 32-bit result. + * However clipping at least gets rid of the case that a + * half-black half-white intra block gets black and white swapped + * and should cause at most minor differences (except for DC). */ + int32_t res = in * quant; + res >>= 11; + if (!dc) + res = av_clip_int16(res); + return res; +} + /** * Read 8x8 block of DCT coefficients. * @@ -669,10 +694,10 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t * quant = quant_matrices[quant_idx]; - block[0] = (block[0] * quant[0]) >> 11; + block[0] = dequant(block[0], quant[0], 1); for (i = 0; i < coef_count; i++) { int idx = coef_idx[i]; - block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11; + block[scan[idx]] = dequant(block[scan[idx]], quant[idx], 0); } return 0; @@ -948,8 +973,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, for (i = 0; i < BINK_NB_SRC; i++) read_bundle(gb, c, i); - ref_start = c->last.data[plane_idx]; - ref_end = c->last.data[plane_idx] + ref_start = c->last.data[plane_idx] ? c->last.data[plane_idx] + : c->pic.data[plane_idx]; + ref_end = ref_start + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; for (i = 0; i < 64; i++) @@ -978,7 +1004,8 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, if (by == bh) break; dst = c->pic.data[plane_idx] + 8*by*stride; - prev = c->last.data[plane_idx] + 8*by*stride; + prev = (c->last.data[plane_idx] ? c->last.data[plane_idx] + : c->pic.data[plane_idx]) + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(c, BINK_SRC_BLOCK_TYPES); // 16x16 block type on odd line means part of the already decoded block, so skip it diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index ff36458c7e..a93131dcbb 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -85,9 +85,9 @@ static av_cold int decode_init(AVCodecContext *avctx) frame_len_bits = 11; } - if (avctx->channels > MAX_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "too many channels: %d\n", avctx->channels); - return -1; + if (avctx->channels < 1 || avctx->channels > MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n", avctx->channels); + return AVERROR_INVALIDDATA; } if (avctx->extradata && avctx->extradata_size > 0) @@ -153,11 +153,18 @@ static const uint8_t rle_length_tab[16] = { 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 }; +#define GET_BITS_SAFE(out, nbits) do { \ + if (get_bits_left(gb) < nbits) \ + return AVERROR_INVALIDDATA; \ + out = get_bits(gb, nbits); \ +} while (0) + /** * Decode Bink Audio block * @param[out] out Output buffer (must contain s->block_size elements) + * @return 0 on success, negative error code on failure */ -static void decode_block(BinkAudioContext *s, short *out, int use_dct) +static int decode_block(BinkAudioContext *s, short *out, int use_dct) { int ch, i, j, k; float q, quant[25]; @@ -170,13 +177,19 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) for (ch = 0; ch < s->channels; ch++) { FFTSample *coeffs = s->coeffs_ptr[ch]; if (s->version_b) { + if (get_bits_left(gb) < 64) + return AVERROR_INVALIDDATA; coeffs[0] = av_int2flt(get_bits(gb, 32)) * s->root; coeffs[1] = av_int2flt(get_bits(gb, 32)) * s->root; } else { + if (get_bits_left(gb) < 58) + return AVERROR_INVALIDDATA; coeffs[0] = get_float(gb) * s->root; coeffs[1] = get_float(gb) * s->root; } + if (get_bits_left(gb) < s->num_bands * 8) + return AVERROR_INVALIDDATA; for (i = 0; i < s->num_bands; i++) { /* constant is result of 0.066399999/log10(M_E) */ int value = get_bits(gb, 8); @@ -191,15 +204,20 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) while (i < s->frame_len) { if (s->version_b) { j = i + 16; - } else if (get_bits1(gb)) { - j = i + rle_length_tab[get_bits(gb, 4)] * 8; } else { - j = i + 8; + int v; + GET_BITS_SAFE(v, 1); + if (v) { + GET_BITS_SAFE(v, 4); + j = i + rle_length_tab[v] * 8; + } else { + j = i + 8; + } } j = FFMIN(j, s->frame_len); - width = get_bits(gb, 4); + GET_BITS_SAFE(width, 4); if (width == 0) { memset(coeffs + i, 0, (j - i) * sizeof(*coeffs)); i = j; @@ -209,9 +227,11 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) while (i < j) { if (s->bands[k] == i) q = quant[k++]; - coeff = get_bits(gb, width); + GET_BITS_SAFE(coeff, width); if (coeff) { - if (get_bits1(gb)) + int v; + GET_BITS_SAFE(v, 1); + if (v) coeffs[i] = -q * coeff; else coeffs[i] = q * coeff; @@ -247,6 +267,8 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) s->overlap_len * s->channels * sizeof(*out)); s->first = 0; + + return 0; } static av_cold int decode_end(AVCodecContext *avctx) @@ -278,12 +300,17 @@ static int decode_frame(AVCodecContext *avctx, int reported_size; GetBitContext *gb = &s->gb; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + init_get_bits(gb, buf, buf_size * 8); reported_size = get_bits_long(gb, 32); - while (get_bits_count(gb) / 8 < buf_size && - samples + s->block_size <= samples_end) { - decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT); + while (samples + s->block_size <= samples_end) { + if (decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT)) + break; samples += s->block_size; get_bits_align32(gb); } diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index f0fa9652c6..e2a3d56d05 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -109,8 +109,8 @@ static int alloc_table(VLC *vlc, int size, int use_static) if(use_static) abort(); //cant do anything, init_vlc() is used with too little memory vlc->table_allocated += (1 << vlc->bits); - vlc->table = av_realloc(vlc->table, - sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + vlc->table = av_realloc_f(vlc->table, + vlc->table_allocated, sizeof(VLC_TYPE) * 2); if (!vlc->table) return -1; } diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c index 4c5166404b..accff13f04 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -219,9 +219,6 @@ static int bmp_decode_frame(AVCodecContext *avctx, if(comp == BMP_RLE4 || comp == BMP_RLE8) memset(p->data[0], 0, avctx->height * p->linesize[0]); - if(depth == 4 || depth == 8) - memset(p->data[1], 0, 1024); - if(height > 0){ ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; linesize = -p->linesize[0]; @@ -232,6 +229,9 @@ static int bmp_decode_frame(AVCodecContext *avctx, if(avctx->pix_fmt == PIX_FMT_PAL8){ int colors = 1 << depth; + + memset(p->data[1], 0, 1024); + if(ihsize >= 36){ int t; buf = buf0 + 46; diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index b56f6ce743..7ca36f8ad3 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -26,6 +26,10 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" +typedef struct { + const uint8_t *buffer, *buffer_end; +} GetByteContext; + #define DEF_T(type, name, bytes, read, write) \ static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\ (*b) += bytes;\ @@ -34,6 +38,18 @@ static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\ static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\ write(*b, value);\ (*b) += bytes;\ +}\ +static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\ +{\ + if (g->buffer_end - g->buffer < bytes)\ + return 0;\ + return bytestream_get_ ## name(&g->buffer);\ +}\ +static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\ +{\ + if (g->buffer_end - g->buffer < bytes)\ + return 0;\ + return read(g->buffer);\ } #define DEF(name, bytes, read, write) \ @@ -55,6 +71,34 @@ DEF (byte, 1, AV_RB8 , AV_WB8 ) #undef DEF64 #undef DEF_T +static av_always_inline void bytestream2_init(GetByteContext *g, + const uint8_t *buf, int buf_size) +{ + g->buffer = buf; + g->buffer_end = buf + buf_size; +} + +static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g) +{ + return g->buffer_end - g->buffer; +} + +static av_always_inline void bytestream2_skip(GetByteContext *g, + unsigned int size) +{ + g->buffer += FFMIN(g->buffer_end - g->buffer, size); +} + +static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, + uint8_t *dst, + unsigned int size) +{ + int size2 = FFMIN(g->buffer_end - g->buffer, size); + memcpy(dst, g->buffer, size2); + g->buffer += size2; + return size2; +} + static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size) { memcpy(dst, *b, size); diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 76253afe3e..9acc2a079f 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -161,10 +161,14 @@ void ff_init_cabac_states(CABACContext *c){ ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1; if( i ){ + ff_h264_lps_state[2*i+0]= ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0; + ff_h264_lps_state[2*i+1]= ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1; }else{ + ff_h264_lps_state[2*i+0]= ff_h264_mlps_state[128-2*i-1]= 1; + ff_h264_lps_state[2*i+1]= ff_h264_mlps_state[128-2*i-2]= 0; } } @@ -190,7 +194,8 @@ int main(void){ ff_init_cabac_states(&c); for(i=0; i>8)&1; } for(i=0; iblock; @@ -124,6 +125,8 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, level_code = get_ue_code(gb,r->golomb_order); if(level_code >= ESCAPE_CODE) { run = ((level_code - ESCAPE_CODE) >> 1) + 1; + if(run > 64) + return -1; esc_code = get_ue_code(gb,esc_golomb_order); level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); while(level > r->inc_limit) @@ -163,7 +166,7 @@ static inline int decode_residual_inter(AVSContext *h) { /* get coded block pattern */ int cbp= get_ue_golomb(&h->s.gb); - if(cbp > 63){ + if(cbp > 63U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n"); return -1; } @@ -189,7 +192,8 @@ static inline int decode_residual_inter(AVSContext *h) { static int decode_mb_i(AVSContext *h, int cbp_code) { GetBitContext *gb = &h->s.gb; - int block, pred_mode_uv; + unsigned pred_mode_uv; + int block; uint8_t top[18]; uint8_t *left = NULL; uint8_t *d; @@ -222,7 +226,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) { /* get coded block pattern */ if(h->pic_type == AV_PICTURE_TYPE_I) cbp_code = get_ue_golomb(gb); - if(cbp_code > 63){ + if(cbp_code > 63U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); return -1; } @@ -445,6 +449,8 @@ static inline int check_for_slice(AVSContext *h) { if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) { skip_bits_long(gb,24+align); h->stc = get_bits(gb,8); + if (h->stc >= h->mb_height) + return 0; decode_slice_header(h,gb); return 1; } @@ -603,12 +609,21 @@ static int decode_pic(AVSContext *h) { static int decode_seq_header(AVSContext *h) { MpegEncContext *s = &h->s; int frame_rate_code; + int width, height; h->profile = get_bits(&s->gb,8); h->level = get_bits(&s->gb,8); skip_bits1(&s->gb); //progressive sequence - s->width = get_bits(&s->gb,14); - s->height = get_bits(&s->gb,14); + + width = get_bits(&s->gb, 14); + height = get_bits(&s->gb, 14); + if ((s->width || s->height) && (s->width != width || s->height != height)) { + av_log_missing_feature(s, "Width/height changing in CAVS is", 0); + return AVERROR_PATCHWELCOME; + } + s->width = width; + s->height = height; + skip_bits(&s->gb,2); //chroma format skip_bits(&s->gb,3); //sample_precision h->aspect_ratio = get_bits(&s->gb,4); @@ -659,7 +674,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, buf_end = buf + buf_size; for(;;) { buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc); - if(stc & 0xFFFFFE00) + if((stc & 0xFFFFFE00) || buf_ptr == buf_end) return FFMAX(0, buf_ptr - buf - s->parse_context.last_index); input_size = (buf_end - buf_ptr)*8; switch(stc) { diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index aae7bbbb1b..3edeefc6d7 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -280,6 +280,10 @@ static int cdg_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n"); return AVERROR(EINVAL); } + if (buf_size > CDG_HEADER_SIZE + CDG_DATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "buffer too big for decoder\n"); + return AVERROR(EINVAL); + } ret = avctx->reget_buffer(avctx, &cc->frame); if (ret) { diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c index 8b68c2ffef..229d7576ea 100644 --- a/libavcodec/celp_filters.c +++ b/libavcodec/celp_filters.c @@ -133,9 +133,8 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, out2 -= val * old_out2; out3 -= val * old_out3; - old_out3 = out[-5]; - for (i = 5; i <= filter_length; i += 2) { + old_out3 = out[-i]; val = filter_coeffs[i-1]; out0 -= val * old_out3; @@ -154,7 +153,6 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, FFSWAP(float, old_out0, old_out2); old_out1 = old_out3; - old_out3 = out[-i-2]; } tmp0 = out0; diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index 57657afaa4..13bc9f1cad 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -67,7 +67,6 @@ typedef struct CinepakContext { int sega_film_skip_bytes; - uint32_t pal[256]; } CinepakContext; static void cinepak_decode_codebook (cvid_codebook *codebook, @@ -336,7 +335,8 @@ static int cinepak_decode (CinepakContext *s) * If the frame header is followed by the bytes FE 00 00 06 00 00 then * this is probably one of the two known files that have 6 extra bytes * after the frame header. Else, assume 2 extra bytes. */ - if ((s->data[10] == 0xFE) && + if (s->size >= 16 && + (s->data[10] == 0xFE) && (s->data[11] == 0x00) && (s->data[12] == 0x00) && (s->data[13] == 0x06) && @@ -365,6 +365,8 @@ static int cinepak_decode (CinepakContext *s) s->strips[i].x2 = s->avctx->width; strip_size = AV_RB24 (&s->data[1]) - 12; + if(strip_size < 0) + return -1; s->data += 12; strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size; @@ -396,7 +398,7 @@ static av_cold int cinepak_decode_init(AVCodecContext *avctx) s->sega_film_skip_bytes = -1; /* uninitialized state */ // check for paletted data - if (avctx->bits_per_coded_sample != 8) { + if ((avctx->palctrl == NULL) || (avctx->bits_per_coded_sample == 40)) { s->palette_video = 0; avctx->pix_fmt = PIX_FMT_YUV420P; } else { @@ -429,18 +431,16 @@ static int cinepak_decode_frame(AVCodecContext *avctx, return -1; } - if (s->palette_video) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - if (pal) { - s->frame.palette_has_changed = 1; - memcpy(s->pal, pal, AVPALETTE_SIZE); - } - } - cinepak_decode(s); - if (s->palette_video) - memcpy (s->frame.data[1], s->pal, AVPALETTE_SIZE); + if (s->palette_video) { + memcpy (s->frame.data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + if (avctx->palctrl->palette_changed) { + s->frame.palette_has_changed = 1; + avctx->palctrl->palette_changed = 0; + } else + s->frame.palette_has_changed = 0; + } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c index c9b0911674..e94ad9b42e 100644 --- a/libavcodec/cljr.c +++ b/libavcodec/cljr.c @@ -67,7 +67,7 @@ static int decode_frame(AVCodecContext *avctx, p->pict_type= AV_PICTURE_TYPE_I; p->key_frame= 1; - init_get_bits(&a->gb, buf, buf_size); + init_get_bits(&a->gb, buf, buf_size * 8); for(y=0; yheight; y++){ uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ]; diff --git a/libavcodec/cook.c b/libavcodec/cook.c index f0dee7905a..14614c9316 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -335,7 +335,7 @@ static av_cold int cook_decode_close(AVCodecContext *avctx) * Fill the gain array for the timedomain quantization. * * @param gb pointer to the GetBitContext - * @param gaininfo[9] array of gain indexes + * @param gaininfo array[9] of gain indexes */ static void decode_gain_info(GetBitContext *gb, int *gaininfo) @@ -1066,6 +1066,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->sample_rate = avctx->sample_rate; q->nb_channels = avctx->channels; q->bit_rate = avctx->bit_rate; + if (!q->nb_channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR_INVALIDDATA; + } /* Initialize RNG. */ av_lfg_init(&q->random_state, 0); @@ -1079,9 +1083,14 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } - if (avctx->extradata_size >= 8){ + if (extradata_size >= 8){ bytestream_get_be32(&edata_ptr); //Unknown unused q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); + if (q->subpacket[s].js_subband_start >= 51) { + av_log(avctx, AV_LOG_ERROR, "js_subband_start %d is too large\n", q->subpacket[s].js_subband_start); + return AVERROR_INVALIDDATA; + } + q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } @@ -1175,8 +1184,9 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) return -1; } - if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 0)) { - av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->subpacket[s].js_vlc_bits); + if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 2*q->subpacket[s].joint_stereo)) { + av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= %d and <= 6 allowed!\n", + q->subpacket[s].js_vlc_bits, 2*q->subpacket[s].joint_stereo); return -1; } diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c index 9255503e05..45268e6687 100644 --- a/libavcodec/cscd.c +++ b/libavcodec/cscd.c @@ -228,7 +228,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { av_log(avctx, AV_LOG_ERROR, "CamStudio codec error: invalid depth %i bpp\n", avctx->bits_per_coded_sample); - return 1; + return AVERROR_INVALIDDATA; } c->bpp = avctx->bits_per_coded_sample; avcodec_get_frame_defaults(&c->pic); @@ -242,7 +242,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); if (!c->decomp_buf) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; + return AVERROR(ENOMEM); } return 0; } diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 4b445bc743..9a5c36df9a 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -29,6 +29,7 @@ #include "libavutil/common.h" #include "libavutil/intmath.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" #include "libavutil/audioconvert.h" #include "avcodec.h" #include "dsputil.h" @@ -898,15 +899,17 @@ static void qmf_32_subbands(DCAContext * s, int chans, else /* Perfect reconstruction */ prCoeff = fir_32bands_perfect; + for (i = sb_act; i < 32; i++) + s->raXin[i] = 0.0; + /* Reconstructed channel sample index */ for (subindex = 0; subindex < 8; subindex++) { /* Load in one sample from each subband and clear inactive subbands */ for (i = 0; i < sb_act; i++){ - uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ ((i-1)&2)<<30; + unsigned sign = (i - 1) & 2; + uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30; AV_WN32A(&s->raXin[i], v); } - for (; i < 32; i++) - s->raXin[i] = 0.0; s->synth.synth_filter_float(&s->imdct, s->subband_fir_hist[chans], &s->hist_index[chans], @@ -1650,6 +1653,7 @@ static int dca_decode_frame(AVCodecContext * avctx, //set AVCodec values with parsed data avctx->sample_rate = s->sample_rate; avctx->bit_rate = s->bit_rate; + avctx->frame_size = s->sample_blocks * 32; s->profile = FF_PROFILE_DTS; diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index 598fedc980..aacdecc447 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -23,6 +23,8 @@ #include "avcodec.h" #include "libavutil/intreadwrite.h" #include "bytestream.h" + +#include "libavutil/imgutils.h" #include "libavutil/lzo.h" // for av_memcpy_backptr typedef struct DfaContext { @@ -35,9 +37,13 @@ typedef struct DfaContext { static av_cold int dfa_decode_init(AVCodecContext *avctx) { DfaContext *s = avctx->priv_data; + int ret; avctx->pix_fmt = PIX_FMT_PAL8; + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; + s->frame_buf = av_mallocz(avctx->width * avctx->height + AV_LZO_OUTPUT_PADDING); if (!s->frame_buf) return AVERROR(ENOMEM); @@ -153,8 +159,7 @@ static int decode_dds1(uint8_t *frame, int width, int height, bitbuf = bytestream_get_le16(&src); mask = 1; } - if (src_end - src < 2 || frame_end - frame < 2) - return -1; + if (bitbuf & mask) { v = bytestream_get_le16(&src); offset = (v & 0x1FFF) << 2; @@ -168,8 +173,13 @@ static int decode_dds1(uint8_t *frame, int width, int height, frame += 2; } } else if (bitbuf & (mask << 1)) { - frame += bytestream_get_le16(&src) * 2; + v = bytestream_get_le16(&src)*2; + if (frame - frame_end < v) + return AVERROR_INVALIDDATA; + frame += v; } else { + if (frame_end - frame < width + 3) + return AVERROR_INVALIDDATA; frame[0] = frame[1] = frame[width] = frame[width + 1] = *src++; frame += 2; @@ -231,6 +241,7 @@ static int decode_wdlt(uint8_t *frame, int width, int height, const uint8_t *frame_end = frame + width * height; uint8_t *line_ptr; int count, i, v, lines, segments; + int y = 0; lines = bytestream_get_le16(&src); if (lines > height || src >= src_end) @@ -239,10 +250,12 @@ static int decode_wdlt(uint8_t *frame, int width, int height, while (lines--) { segments = bytestream_get_le16(&src); while ((segments & 0xC000) == 0xC000) { + unsigned skip_lines = -(int16_t)segments; unsigned delta = -((int16_t)segments * width); - if (frame_end - frame <= delta) + if (frame_end - frame <= delta || y + lines + skip_lines > height) return -1; frame += delta; + y += skip_lines; segments = bytestream_get_le16(&src); } if (segments & 0x8000) { @@ -250,7 +263,10 @@ static int decode_wdlt(uint8_t *frame, int width, int height, segments = bytestream_get_le16(&src); } line_ptr = frame; + if (frame_end - frame < width) + return AVERROR_INVALIDDATA; frame += width; + y++; while (segments--) { if (src_end - src < 2) return -1; diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index af0d799acc..1582a5f8f2 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -120,7 +120,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, // chroma subsampling if (get_bits1(gb)) source->chroma_format = svq3_get_ue_golomb(gb); - if (source->chroma_format > 2) { + if (source->chroma_format > 2U) { av_log(avctx, AV_LOG_ERROR, "Unknown chroma format %d\n", source->chroma_format); return -1; @@ -128,14 +128,14 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, if (get_bits1(gb)) source->interlaced = svq3_get_ue_golomb(gb); - if (source->interlaced > 1) + if (source->interlaced > 1U) return -1; // frame rate if (get_bits1(gb)) { source->frame_rate_index = svq3_get_ue_golomb(gb); - if (source->frame_rate_index > 10) + if (source->frame_rate_index > 10U) return -1; if (!source->frame_rate_index) { @@ -156,7 +156,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, if (get_bits1(gb)) { source->aspect_ratio_index = svq3_get_ue_golomb(gb); - if (source->aspect_ratio_index > 6) + if (source->aspect_ratio_index > 6U) return -1; if (!source->aspect_ratio_index) { @@ -179,7 +179,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, if (get_bits1(gb)) { source->pixel_range_index = svq3_get_ue_golomb(gb); - if (source->pixel_range_index > 4) + if (source->pixel_range_index > 4U) return -1; // This assumes either fullrange or MPEG levels only @@ -207,7 +207,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, if (get_bits1(gb)) { idx = source->color_spec_index = svq3_get_ue_golomb(gb); - if (source->color_spec_index > 4) + if (source->color_spec_index > 4U) return -1; avctx->color_primaries = dirac_color_presets[idx].color_primaries; @@ -217,7 +217,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, if (!source->color_spec_index) { if (get_bits1(gb)) { idx = svq3_get_ue_golomb(gb); - if (idx < 3) + if (idx < 3U) avctx->color_primaries = dirac_primaries[idx]; } @@ -259,7 +259,7 @@ int ff_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, else if (version_major > 2) av_log(avctx, AV_LOG_WARNING, "Stream may have unhandled features\n"); - if (video_format > 20) + if (video_format > 20U) return -1; // Fill in defaults for the source parameters. diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 62bc9f0dd5..0c2a965eb7 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -151,7 +151,7 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) static int dnxhd_init_rc(DNXHDEncContext *ctx) { - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail); + FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*(ctx->m.avctx->qmax + 1)*sizeof(RCEntry), fail); if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail); diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index ee8eb6a722..947e1cb31e 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -169,6 +169,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, int in, out = 0; int predictor[2]; int channel_number = 0; + int stereo = s->channels - 1; short *output_samples = data; int shift[2]; unsigned char byte; @@ -177,6 +178,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, if (!buf_size) return 0; + if (stereo && (buf_size & 1)) + buf_size--; + // almost every DPCM variant expands one byte of data into two if(*data_size/2 < buf_size) return -1; @@ -295,7 +299,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, } *data_size = out * sizeof(short); - return buf_size; + return avpkt->size; } #define DPCM_DECODER(id, name, long_name_) \ diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index f12560714a..3163e10b1a 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -146,11 +146,11 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c return dst_cur - dst; } -static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) { uint16_t cmd; int i, sz, offset, code; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_end = dst + dst_size, *dst_start = dst; const unsigned char *src_end = src + src_size; while (src < src_end && dst < dst_end) { @@ -161,6 +161,8 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha } else { cmd = AV_RL16(src); src += 2; offset = cmd >> 4; + if ((int) (dst - dst_start) < offset + 1) + return AVERROR_INVALIDDATA; sz = (cmd & 0xF) + 2; /* don't use memcpy/memmove here as the decoding routine (ab)uses */ /* buffer overlappings to repeat bytes in the destination */ @@ -172,6 +174,8 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha } } } + + return 0; } static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) @@ -201,13 +205,7 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, 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; - - cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &cin->frame)) { - av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); - return -1; - } + 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); @@ -217,7 +215,11 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, bitmap_frame_size = buf_size - 4; /* handle palette */ + if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0))) + return AVERROR_INVALIDDATA; if (palette_type == 0) { + if (palette_colors_count > 256) + return AVERROR_INVALIDDATA; for (i = 0; i < palette_colors_count; ++i) { cin->palette[i] = bytestream_get_le24(&buf); bitmap_frame_size -= 3; @@ -229,8 +231,6 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, bitmap_frame_size -= 4; } } - memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); - cin->frame.palette_has_changed = 1; /* note: the decoding routines below assumes that surface.width = surface.pitch */ switch (bitmap_frame_type) { @@ -263,17 +263,31 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 38: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + res = cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_size); + if (res < 0) + return res; break; case 39: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + res = cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_size); + if (res < 0) + return res; cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; } + cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &cin->frame)) { + av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); + return -1; + } + + memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); + cin->frame.palette_has_changed = 1; for (y = 0; y < cin->avctx->height; ++y) memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, @@ -306,6 +320,11 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx) CinAudioContext *cin = avctx->priv_data; cin->avctx = avctx; + if (avctx->channels != 1) { + av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); + return AVERROR_PATCHWELCOME; + } + cin->initial_decode_frame = 1; cin->delta = 0; avctx->sample_fmt = AV_SAMPLE_FMT_S16; diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 0e596b1b01..e7efde3945 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -1914,7 +1914,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); @@ -1939,7 +1939,7 @@ static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ } }else #endif - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for(i=0; i<=w-(int)sizeof(long); i+=sizeof(long)){ long a = *(long*)(src1+i); long b = *(long*)(src2+i); *(long*)(dst+i) = ((a|pb_80) - (b&pb_7f)) ^ ((a^b^pb_80)&pb_80); @@ -2836,7 +2836,7 @@ int ff_check_alignment(void){ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) { - int i; + int i, j; ff_check_alignment(); @@ -3222,11 +3222,15 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) if (ARCH_SH4) dsputil_init_sh4 (c, avctx); if (ARCH_BFIN) dsputil_init_bfin (c, avctx); - for(i=0; i<64; i++){ - if(!c->put_2tap_qpel_pixels_tab[0][i]) - c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; - if(!c->avg_2tap_qpel_pixels_tab[0][i]) - c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + if(!c->put_2tap_qpel_pixels_tab[i][j]) + c->put_2tap_qpel_pixels_tab[i][j] = + c->put_h264_qpel_pixels_tab[i][j]; + if(!c->avg_2tap_qpel_pixels_tab[i][j]) + c->avg_2tap_qpel_pixels_tab[i][j] = + c->avg_h264_qpel_pixels_tab[i][j]; + } } c->put_rv30_tpel_pixels_tab[0][0] = c->put_h264_qpel_pixels_tab[0][0]; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 0143ed7d3c..8dd26849e9 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -120,6 +120,14 @@ void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); /* 1/2^n downscaling functions from imgconvert.c */ +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Use av_image_copy_plane() instead. + */ +attribute_deprecated +void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +#endif + void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index 5b09eb14d6..e43dd29a14 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -1360,7 +1360,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, rect->y = display->y_pos + offset_y; rect->w = region->width; rect->h = region->height; - rect->nb_colors = 16; + rect->nb_colors = (1 << region->depth); rect->type = SUBTITLE_BITMAP; rect->pict.linesize[0] = region->width; diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c index 05993d874f..db6ed2b871 100644 --- a/libavcodec/dvdata.c +++ b/libavcodec/dvdata.c @@ -248,11 +248,13 @@ static const DVprofile dv_profiles[] = { const DVprofile* ff_dv_frame_profile(const DVprofile *sys, const uint8_t* frame, unsigned buf_size) { - int i; + int i, dsf, stype; - int dsf = (frame[3] & 0x80) >> 7; + if(buf_size < DV_PROFILE_BYTES) + return NULL; - int stype = frame[80*5 + 48 + 3] & 0x1f; + dsf = (frame[3] & 0x80) >> 7; + stype = frame[80*5 + 48 + 3] & 0x1f; /* 576i50 25Mbps 4:1:1 is a special case */ if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) { diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index 807ecd85ee..7f4321ce91 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -295,6 +295,11 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + if (avctx->width%4 || avctx->height%4) { + av_log(avctx, AV_LOG_ERROR, "dimensions are not a multiple of 4"); + return AVERROR_INVALIDDATA; + } + avcodec_get_frame_defaults(&c->pic); avcodec_get_frame_defaults(&c->prev); diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index bc80e982fb..3f728e27b5 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -158,9 +158,10 @@ static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm) for (j = 0; j < 16; j++) qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]]; - for (i = 0; i < 2; i++) - for (j = 0; j < 64; j++) - qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]]; + for (j = 0; j < 64; j++) { + qm->bScalingLists8x8[0][j] = h->pps.scaling_matrix8[0][ff_zigzag_direct[j]]; + qm->bScalingLists8x8[1][j] = h->pps.scaling_matrix8[3][ff_zigzag_direct[j]]; + } } static int is_slice_short(struct dxva_context *ctx) diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index 23d4d87522..fcf45bc664 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -25,7 +25,14 @@ #define _WIN32_WINNT 0x0600 #define COBJMACROS + +#include "config.h" + #include "dxva2.h" +#if HAVE_DXVA_H +#include +#endif + #include "avcodec.h" #include "mpegvideo.h" diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 408d948812..4cd6a6fd1f 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -56,7 +56,7 @@ static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t * unsigned char *dst = s->frame.data[0]; int i; - for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) { + for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) { memcpy(dst, buf, s->avctx->width); dst += s->frame.linesize[0]; buf += s->avctx->width; @@ -88,7 +88,7 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * i = 0; for(y=0; yavctx->height/4; y++) - for(x=0; xavctx->width/4 && buf+iavctx->width/4 && buf_end - buf > i; x++) { if (buf[i]==0xFF) { unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4; if (raw+16> 4)) - 7; - 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); + 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); } i++; } @@ -122,7 +123,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t { int pal_start, pal_count, i; - if(buf+16>=buf_end) { + if(buf_end - buf < 16) { av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); return; } @@ -139,7 +140,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t pal_count = AV_RL16(&buf[14]); buf += 16; - for (i=pal_start; i= 3; i++) { s->palette[i] = AV_RB24(buf); buf += 3; } @@ -157,6 +158,9 @@ static int cmv_decode_frame(AVCodecContext *avctx, CmvContext *s = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; + if (buf_end - buf < EA_PREAMBLE_SIZE) + return AVERROR_INVALIDDATA; + if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); return buf_size; diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index d4881ab843..a431bbcdd5 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -85,15 +85,21 @@ static inline void comp_block(MadContext *t, int mb_x, int mb_y, { MpegEncContext *s = &t->s; if (j < 4) { + unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x; + if (offset >= (s->height - 7) * t->last_frame.linesize[0] - 7) + return; comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), t->frame.linesize[0], - t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x, + t->last_frame.data[0] + offset, t->last_frame.linesize[0], add); } else if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; + unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2); + if (offset >= (s->height/2 - 7) * t->last_frame.linesize[index] - 7) + return; comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8, t->frame.linesize[index], - t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2), + t->last_frame.data[index] + offset, t->last_frame.linesize[index], add); } } @@ -205,7 +211,8 @@ static void decode_mb(MadContext *t, int inter) for (j=0; j<6; j++) { if (mv_map & (1<gb); - comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add); + if (t->last_frame.data[0]) + comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add); } else { s->dsp.clear_block(t->block); decode_block_intra(t, t->block); @@ -242,7 +249,7 @@ static int decode_frame(AVCodecContext *avctx, int chunk_type; int inter; - if (buf_size < 17) { + if (buf_size < 26) { av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n"); *data_size = 0; return -1; @@ -266,6 +273,8 @@ static int decode_frame(AVCodecContext *avctx, avcodec_set_dimensions(avctx, s->width, s->height); if (t->frame.data[0]) avctx->release_buffer(avctx, &t->frame); + if (t->last_frame.data[0]) + avctx->release_buffer(avctx, &t->last_frame); } t->frame.reference = 1; @@ -280,6 +289,7 @@ static int decode_frame(AVCodecContext *avctx, if (!t->bitstream_buf) return AVERROR(ENOMEM); bswap16_buf(t->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2); + memset((uint8_t*)t->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf)); for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++) diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index 0855f10417..fb88dce5d3 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -74,7 +74,7 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst else src += 2; - if (src+3>src_end) + if (src_end - src < 3) return -1; size = AV_RB24(src); src += 3; @@ -138,7 +138,7 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst * @return 0 on success, -1 on critical buffer underflow */ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){ - unsigned char *frame0_end = s->last_frame.data[0] + s->avctx->width*s->last_frame.linesize[0]; + unsigned last_frame_size = s->avctx->height*s->last_frame.linesize[0]; int num_mvs; int num_blocks_raw; int num_blocks_packed; @@ -148,7 +148,7 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b int mvbits; const unsigned char *blocks_raw; - if(buf+12>buf_end) + if(buf_end - buf < 12) return -1; num_mvs = AV_RL16(&buf[0]); @@ -171,7 +171,7 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b /* read motion vectors */ mvbits = (num_mvs*2*10+31) & ~31; - if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end) + if (buf_end - buf < (mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed) return -1; init_get_bits(&gb, buf, mvbits); @@ -207,12 +207,14 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b int src_stride; if (vector < num_mvs) { - src = s->last_frame.data[0] + - (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] + - x*4 + s->mv_codebook[vector][0]; + unsigned offset = + (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] + + x*4 + s->mv_codebook[vector][0]; + src_stride = s->last_frame.linesize[0]; - if (src+3*src_stride+3>=frame0_end) + if (offset >= last_frame_size - (3*src_stride+3)) continue; + src = s->last_frame.data[0] + offset; }else{ int offset = vector - num_mvs; if (offsetbuf_end) { + if(buf_end - buf < 12) { av_log(avctx, AV_LOG_WARNING, "truncated header\n"); return -1; } @@ -272,7 +277,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, pal_count = AV_RL16(&buf[6]); buf += 12; - for(i=0; i= 3; i++) { s->palette[i] = AV_RB24(buf); buf += 3; } diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 44792f0483..09992f5611 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -59,12 +59,15 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx) return 0; } -static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) +static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) { int n; s->dsp.clear_blocks(block[0]); for (n=0; n<6; n++) - ff_mpeg1_decode_block_intra(s, block[n], n); + if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0) + return -1; + + return 0; } static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64]) @@ -136,7 +139,8 @@ static int tqi_decode_frame(AVCodecContext *avctx, for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++) { - tqi_decode_mb(s, t->block); + if (tqi_decode_mb(s, t->block) < 0) + break; tqi_idct_put(t, t->block); } diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index d6ac81f009..0e410f96e8 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -660,7 +660,7 @@ static int is_intra_more_likely(MpegEncContext *s){ if(s->codec_id == CODEC_ID_H264){ H264Context *h= (void*)s; - if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0]) + if (h->list_count <= 0 || h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0]) return 1; } diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 34aa576660..099581192b 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -243,7 +243,7 @@ static void put_line(uint8_t *dst, int size, int width, const int *runs) PutBitContext pb; int run, mode = ~0, pix_left = width, run_idx = 0; - init_put_bits(&pb, dst, size*8); + init_put_bits(&pb, dst, size); while(pix_left > 0){ run = runs[run_idx++]; mode = ~mode; diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index a0a4a1d009..ebf3a57569 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -522,7 +522,7 @@ static av_always_inline int encode_line(FFV1Context *s, int w, int run_mode=0; if(s->ac){ - if(c->bytestream_end - c->bytestream < w*20){ + if(c->bytestream_end - c->bytestream < w*35){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } @@ -1805,7 +1805,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac bytes_read = c->bytestream - c->bytestream_start - 1; if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME //printf("pos=%d\n", bytes_read); - init_get_bits(&f->slice_context[0]->gb, buf + bytes_read, buf_size - bytes_read); + init_get_bits(&f->slice_context[0]->gb, buf + bytes_read, (buf_size - bytes_read) * 8); } else { bytes_read = 0; /* avoid warning */ } @@ -1822,7 +1822,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if(fs->ac){ ff_init_range_decoder(&fs->c, buf_p, v); }else{ - init_get_bits(&fs->gb, buf_p, v); + init_get_bits(&fs->gb, buf_p, v * 8); } } diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 50ad72b7c0..dac1c26c7e 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -646,7 +646,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, handle_error: *poutbuf = NULL; *poutbuf_size = 0; - return read_end - buf; + return buf_size ? read_end - buf : 0; } static int flac_parse_init(AVCodecParserContext *c) diff --git a/libavcodec/flacdata.c b/libavcodec/flacdata.c index 6fcbe3955a..1954f32d32 100644 --- a/libavcodec/flacdata.c +++ b/libavcodec/flacdata.c @@ -27,7 +27,7 @@ const int ff_flac_sample_rate_table[16] = 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 0, 0, 0, 0 }; -const int16_t ff_flac_blocksize_table[16] = { +const int32_t ff_flac_blocksize_table[16] = { 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, 256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 }; diff --git a/libavcodec/flacdata.h b/libavcodec/flacdata.h index 96a50b9183..e2c1e5d7f2 100644 --- a/libavcodec/flacdata.h +++ b/libavcodec/flacdata.h @@ -26,6 +26,6 @@ extern const int ff_flac_sample_rate_table[16]; -extern const int16_t ff_flac_blocksize_table[16]; +extern const int32_t ff_flac_blocksize_table[16]; #endif /* AVCODEC_FLACDATA_H */ diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index ece095cf09..9a0144d04c 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -228,9 +228,11 @@ static int get_metadata_size(const uint8_t *buf, int buf_size) buf += 4; do { + if (buf_end - buf < 4) + return 0; ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size); buf += 4; - if (buf + metadata_size > buf_end) { + if (buf_end - buf < metadata_size) { /* need more data in order to read the complete header */ return 0; } @@ -418,7 +420,16 @@ static inline int decode_subframe(FLACContext *s, int channel) type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { + int left = get_bits_left(&s->gb); wasted = 1; + if ( left < 0 || + (left < s->curr_bps && !show_bits_long(&s->gb, left)) || + !show_bits_long(&s->gb, s->curr_bps)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid number of wasted bits > available bits (%d) - left=%d\n", + s->curr_bps, left); + return AVERROR_INVALIDDATA; + } while (!get_bits1(&s->gb)) wasted++; s->curr_bps -= wasted; diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index a80f0f9fe3..e38f6bd839 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -296,6 +296,17 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8})[level]; /* set compression option overrides from AVCodecContext */ +#if FF_API_USE_LPC + /* for compatibility with deprecated AVCodecContext.use_lpc */ + if (avctx->use_lpc == 0) { + s->options.lpc_type = AV_LPC_TYPE_FIXED; + } else if (avctx->use_lpc == 1) { + s->options.lpc_type = AV_LPC_TYPE_LEVINSON; + } else if (avctx->use_lpc > 1) { + s->options.lpc_type = AV_LPC_TYPE_CHOLESKY; + s->options.lpc_passes = avctx->use_lpc - 1; + } +#endif #if FF_API_FLAC_GLOBAL_OPTS if (avctx->lpc_type > FF_LPC_TYPE_DEFAULT) { if (avctx->lpc_type > FF_LPC_TYPE_CHOLESKY) { @@ -937,14 +948,16 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) omethod == ORDER_METHOD_8LEVEL) { int levels = 1 << omethod; uint32_t bits[1 << ORDER_METHOD_8LEVEL]; - int order; + int order = -1; int opt_index = levels-1; opt_order = max_order-1; bits[opt_index] = UINT32_MAX; for (i = levels-1; i >= 0; i--) { + int last_order = order; order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1; - if (order < 0) - order = 0; + order = av_clip(order, min_order - 1, max_order - 1); + if (order == last_order) + continue; encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]); bits[i] = find_subframe_rice_params(s, sub, order+1); if (bits[i] < bits[opt_index]) { diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 7ee299cf7c..86a35b6f34 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -270,7 +270,7 @@ static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size) if (buf_size < 5) return -1; - init_put_bits(&pb, buf, buf_size * 8); + init_put_bits(&pb, buf, buf_size); put_bits(&pb, 4, (s->block_width >> 4) - 1); put_bits(&pb, 12, s->image_width); diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c index c0327a911b..8a813f2b14 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -139,7 +139,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 8cc72e241e..2055596503 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -132,7 +132,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, FlicDecodeContext *s = avctx->priv_data; int stream_ptr = 0; - int stream_ptr_after_color_chunk; int pixel_ptr; int palette_ptr; unsigned char palette_idx1; @@ -172,7 +171,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, pixels = s->frame.data[0]; pixel_limit = s->avctx->height * s->frame.linesize[0]; + if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE)) + return AVERROR_INVALIDDATA; frame_size = AV_RL32(&buf[stream_ptr]); + if (frame_size > buf_size) + frame_size = buf_size; stream_ptr += 6; /* skip the magic number */ num_chunks = AV_RL16(&buf[stream_ptr]); stream_ptr += 10; /* skip padding */ @@ -180,13 +183,16 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, frame_size -= 16; /* iterate through the chunks */ - while ((frame_size > 0) && (num_chunks > 0)) { + while ((frame_size >= 6) && (num_chunks > 0)) { + int stream_ptr_after_chunk; chunk_size = AV_RL32(&buf[stream_ptr]); if (chunk_size > frame_size) { av_log(avctx, AV_LOG_WARNING, "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size); chunk_size = frame_size; } + stream_ptr_after_chunk = stream_ptr + chunk_size; + stream_ptr += 4; chunk_type = AV_RL16(&buf[stream_ptr]); stream_ptr += 2; @@ -194,8 +200,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: - stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6; - /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during @@ -219,6 +223,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, if (color_changes == 0) color_changes = 256; + if (stream_ptr + color_changes * 3 > stream_ptr_after_chunk) + break; + for (j = 0; j < color_changes; j++) { unsigned int entry; @@ -235,13 +242,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, s->palette[palette_ptr++] = entry; } } - - /* color chunks sometimes have weird 16-bit alignment issues; - * therefore, take the hardline approach and set the stream_ptr - * to the value calculated w.r.t. the size specified by the color - * chunk header */ - stream_ptr = stream_ptr_after_color_chunk; - break; case FLI_DELTA: @@ -249,6 +249,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, compressed_lines = AV_RL16(&buf[stream_ptr]); stream_ptr += 2; while (compressed_lines > 0) { + if (stream_ptr + 2 > stream_ptr_after_chunk) + break; line_packets = AV_RL16(&buf[stream_ptr]); stream_ptr += 2; if ((line_packets & 0xC000) == 0xC000) { @@ -268,6 +270,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { + if (stream_ptr + 2 > stream_ptr_after_chunk) + break; /* account for the skip bytes */ pixel_skip = buf[stream_ptr++]; pixel_ptr += pixel_skip; @@ -284,6 +288,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } else { CHECK_PIXEL_PTR(byte_run * 2); + if (stream_ptr + byte_run * 2 > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -310,6 +316,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; line_packets = buf[stream_ptr++]; + if (stream_ptr + 2 * line_packets > stream_ptr_after_chunk) + break; if (line_packets > 0) { for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ @@ -319,6 +327,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); + if (stream_ptr + byte_run > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -356,6 +366,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, stream_ptr++; pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { + if (stream_ptr + 1 > stream_ptr_after_chunk) + break; byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { palette_idx1 = buf[stream_ptr++]; @@ -370,6 +382,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); + if (stream_ptr + byte_run > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run; j++) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -387,10 +401,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_COPY: /* copy the chunk (uncompressed frame) */ - if (chunk_size - 6 > s->avctx->width * s->avctx->height) { + if (chunk_size - 6 != s->avctx->width * s->avctx->height) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ - "bigger than image, skipping chunk\n", chunk_size - 6); - stream_ptr += chunk_size - 6; + "has incorrect size, skipping chunk\n", chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; y_ptr += s->frame.linesize[0]) { @@ -403,7 +416,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ - stream_ptr += chunk_size - 6; break; default: @@ -411,6 +423,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, break; } + stream_ptr = stream_ptr_after_chunk; + frame_size -= chunk_size; num_chunks--; } diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 7e96b0d312..ed80038c4a 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -135,7 +135,7 @@ static int decode_frame(AVCodecContext *avctx, uint32_t *luma1,*luma2,*cb,*cr; uint32_t offs[4]; int i, j, is_chroma, planes; - + enum PixelFormat pix_fmt; header = AV_RL32(buf); version = header & 0xff; @@ -152,12 +152,16 @@ static int decode_frame(AVCodecContext *avctx, if (header_size == 8) buf+=4; + pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; + if (avctx->pix_fmt != pix_fmt && f->data[0]) { + avctx->release_buffer(avctx, f); + } + avctx->pix_fmt = pix_fmt; + switch(version) { case 0: default: /* Fraps v0 is a reordered YUV420 */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; - if ( (buf_size != avctx->width*avctx->height*3/2+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -205,8 +209,6 @@ static int decode_frame(AVCodecContext *avctx, case 1: /* Fraps v1 is an upside-down BGR24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - if ( (buf_size != avctx->width*avctx->height*3+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -241,7 +243,6 @@ static int decode_frame(AVCodecContext *avctx, * Fraps v2 is Huffman-coded YUV420 planes * Fraps v4 is virtually the same */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | @@ -286,7 +287,6 @@ static int decode_frame(AVCodecContext *avctx, case 3: case 5: /* Virtually the same as version 4, but is for RGB24 */ - avctx->pix_fmt = PIX_FMT_BGR24; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 39d0db9c24..1c9358f304 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -125,26 +125,21 @@ static int gif_read_image(GifState *s) case 1: y1 += 8; ptr += linesize * 8; - if (y1 >= height) { - y1 = pass ? 2 : 4; - ptr = ptr1 + linesize * y1; - pass++; - } break; case 2: y1 += 4; ptr += linesize * 4; - if (y1 >= height) { - y1 = 1; - ptr = ptr1 + linesize; - pass++; - } break; case 3: y1 += 2; ptr += linesize * 2; break; } + while (y1 >= height) { + y1 = 4 >> pass; + ptr = ptr1 + linesize * y1; + pass++; + } } else { ptr += linesize; } diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 90eeb30b54..c24ff9eee4 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -75,6 +75,20 @@ static inline int get_ue_golomb(GetBitContext *gb){ } } +/** + * Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1. + */ +static inline unsigned get_ue_golomb_long(GetBitContext *gb) +{ + unsigned buf, log; + + buf = show_bits_long(gb, 32); + log = 31 - av_log2(buf); + skip_bits_long(gb, log); + + return get_bits_long(gb, log + 1) - 1; +} + /** * read unsigned exp golomb code, constraint to a max of 31. * the return value is undefined if the stored value exceeds 31. @@ -109,7 +123,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ }else{ int ret = 1; - while (1) { + do { buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); @@ -121,7 +135,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); - } + } while (ret); CLOSE_READER(re, gb); return ret - 1; @@ -287,7 +301,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int return buf; }else{ int i; - for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){ + for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) { LAST_SKIP_BITS(re, gb, 1); UPDATE_CACHE(re, gb); } diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 108bd0e841..856fae3d9c 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -599,6 +599,10 @@ retry: s->current_picture.pict_type= s->pict_type; s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I; +#if FF_API_HURRY_UP + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); +#endif if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 43d5b4b3e9..5f366feac5 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -98,7 +98,7 @@ void ff_h263_update_motion_val(MpegEncContext * s){ } } -int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr) +int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr) { int x, y, wrap, a, c, pred_dc; int16_t *dc_val; @@ -226,7 +226,7 @@ void ff_h263_loop_filter(MpegEncContext * s){ } } -void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) +void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) { int x, y, wrap, a, c, pred_dc, scale, i; int16_t *dc_val, *ac_val, *ac_val1; @@ -313,8 +313,8 @@ void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; } -int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, - int *px, int *py) +int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir, + int *px, int *py) { int wrap; int16_t *A, *B, *C, (*mot_val)[2]; diff --git a/libavcodec/h263.h b/libavcodec/h263.h index b2b6613536..f9021ef9b4 100644 --- a/libavcodec/h263.h +++ b/libavcodec/h263.h @@ -38,16 +38,16 @@ extern const AVRational ff_h263_pixel_aspect[16]; extern const uint8_t ff_h263_cbpy_tab[16][2]; -extern const uint8_t cbpc_b_tab[4][2]; +extern const uint8_t ff_cbpc_b_tab[4][2]; -extern const uint8_t mvtab[33][2]; +extern const uint8_t ff_mvtab[33][2]; extern const uint8_t ff_h263_intra_MCBPC_code[9]; extern const uint8_t ff_h263_intra_MCBPC_bits[9]; extern const uint8_t ff_h263_inter_MCBPC_code[28]; extern const uint8_t ff_h263_inter_MCBPC_bits[28]; -extern const uint8_t h263_mbtype_b_tab[15][2]; +extern const uint8_t ff_h263_mbtype_b_tab[15][2]; extern VLC ff_h263_intra_MCBPC_vlc; extern VLC ff_h263_inter_MCBPC_vlc; @@ -55,41 +55,41 @@ extern VLC ff_h263_cbpy_vlc; extern RLTable ff_h263_rl_inter; -extern RLTable rl_intra_aic; +extern RLTable ff_rl_intra_aic; -extern const uint16_t h263_format[8][2]; -extern const uint8_t modified_quant_tab[2][32]; +extern const uint16_t ff_h263_format[8][2]; +extern const uint8_t ff_modified_quant_tab[2][32]; extern uint16_t ff_mba_max[6]; extern uint8_t ff_mba_length[7]; extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; -int h263_decode_motion(MpegEncContext * s, int pred, int f_code); +int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code); av_const int ff_h263_aspect_to_info(AVRational aspect); int ff_h263_decode_init(AVCodecContext *avctx); int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt); int ff_h263_decode_end(AVCodecContext *avctx); -void h263_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void h263_encode_picture_header(MpegEncContext *s, int picture_number); -void h263_encode_gob_header(MpegEncContext * s, int mb_line); -int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, - int *px, int *py); -void h263_encode_init(MpegEncContext *s); -void h263_decode_init_vlc(MpegEncContext *s); -int h263_decode_picture_header(MpegEncContext *s); +void ff_h263_encode_mb(MpegEncContext *s, + DCTELEM block[6][64], + int motion_x, int motion_y); +void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line); +int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir, + int *px, int *py); +void ff_h263_encode_init(MpegEncContext *s); +void ff_h263_decode_init_vlc(MpegEncContext *s); +int ff_h263_decode_picture_header(MpegEncContext *s); int ff_h263_decode_gob_header(MpegEncContext *s); void ff_h263_update_motion_val(MpegEncContext * s); void ff_h263_loop_filter(MpegEncContext * s); int ff_h263_decode_mba(MpegEncContext *s); void ff_h263_encode_mba(MpegEncContext *s); void ff_init_qscale_tab(MpegEncContext *s); -int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr); -void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n); +int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr); +void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n); /** @@ -119,7 +119,7 @@ static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code int l, bit_size, code; if (val == 0) { - return mvtab[0][1]; + return ff_mvtab[0][1]; } else { bit_size = f_code - 1; /* modulo encoding */ @@ -128,7 +128,7 @@ static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code val--; code = (val >> bit_size) + 1; - return mvtab[code][1] + 1 + bit_size; + return ff_mvtab[code][1] + 1 + bit_size; } } diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h index 81e3ddd2e0..5df873b96d 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -57,7 +57,7 @@ const uint8_t ff_h263_inter_MCBPC_bits[28] = { 11, 13, 13, 13,/* inter4Q*/ }; -const uint8_t h263_mbtype_b_tab[15][2] = { +const uint8_t ff_h263_mbtype_b_tab[15][2] = { {1, 1}, {3, 3}, {1, 5}, @@ -75,7 +75,7 @@ const uint8_t h263_mbtype_b_tab[15][2] = { {1, 8}, }; -const uint8_t cbpc_b_tab[4][2] = { +const uint8_t ff_cbpc_b_tab[4][2] = { {0, 1}, {2, 2}, {7, 3}, @@ -88,7 +88,7 @@ const uint8_t ff_h263_cbpy_tab[16][2] = {2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2} }; -const uint8_t mvtab[33][2] = +const uint8_t ff_mvtab[33][2] = { {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7}, {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, @@ -98,7 +98,7 @@ const uint8_t mvtab[33][2] = }; /* third non intra table */ -const uint16_t inter_vlc[103][2] = { +const uint16_t ff_inter_vlc[103][2] = { { 0x2, 2 },{ 0xf, 4 },{ 0x15, 6 },{ 0x17, 7 }, { 0x1f, 8 },{ 0x25, 9 },{ 0x24, 9 },{ 0x21, 10 }, { 0x20, 10 },{ 0x7, 11 },{ 0x6, 11 },{ 0x20, 11 }, @@ -127,7 +127,7 @@ const uint16_t inter_vlc[103][2] = { { 0x5e, 12 },{ 0x5f, 12 },{ 0x3, 7 }, }; -const int8_t inter_level[102] = { +const int8_t ff_inter_level[102] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, @@ -143,7 +143,7 @@ const int8_t inter_level[102] = { 1, 1, 1, 1, 1, 1, }; -const int8_t inter_run[102] = { +const int8_t ff_inter_run[102] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, @@ -162,9 +162,9 @@ const int8_t inter_run[102] = { RLTable ff_h263_rl_inter = { 102, 58, - inter_vlc, - inter_run, - inter_level, + ff_inter_vlc, + ff_inter_run, + ff_inter_level, }; static const uint16_t intra_vlc_aic[103][2] = { @@ -228,7 +228,7 @@ static const int8_t intra_level_aic[102] = { 1, 1, 1, 1, 1, 1, }; -RLTable rl_intra_aic = { +RLTable ff_rl_intra_aic = { 102, 58, intra_vlc_aic, @@ -236,7 +236,7 @@ RLTable rl_intra_aic = { intra_level_aic, }; -const uint16_t h263_format[8][2] = { +const uint16_t ff_h263_format[8][2] = { { 0, 0 }, { 128, 96 }, { 176, 144 }, @@ -250,7 +250,7 @@ const uint8_t ff_aic_dc_scale_table[32]={ 0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 }; -const uint8_t modified_quant_tab[2][32]={ +const uint8_t ff_modified_quant_tab[2][32]={ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 { 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11,12,13,14,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28 diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index f079557759..636adef4b1 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -111,7 +111,7 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; - h263_decode_init_vlc(s); + ff_h263_decode_init_vlc(s); return 0; } @@ -380,7 +380,7 @@ uint64_t time= rdtsc(); retry: - if(s->divx_packed && s->xvid_build>=0 && s->bitstream_buffer_size){ + if(s->divx_packed && s->bitstream_buffer_size){ int i; for(i=0; ih263_flv) { ret = ff_flv_decode_picture_header(s); } else { - ret = h263_decode_picture_header(s); + ret = ff_h263_decode_picture_header(s); } if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size); @@ -438,6 +438,13 @@ retry: if (ret < 0){ av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return -1; + } else if ((s->width != avctx->coded_width || + s->height != avctx->coded_height || + (s->width + 15) >> 4 != s->mb_width || + (s->height + 15) >> 4 != s->mb_height) && + (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding } avctx->has_b_frames= !s->low_delay; @@ -564,8 +571,7 @@ retry: #if HAVE_MMX if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { avctx->idct_algo= FF_IDCT_XVIDMMX; - avctx->coded_width= 0; // force reinit -// dsputil_init(&s->dsp, avctx); + ff_dct_common_init(s); s->picture_number=0; } #endif @@ -579,6 +585,12 @@ retry: || s->height != avctx->coded_height) { /* H.263 could change picture size any time */ ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + + if (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return -1; // width / height changed during parallelized decoding + } + s->parse_context.buffer=0; MPV_common_end(s); s->parse_context= pc; @@ -598,10 +610,18 @@ retry: /* skip B-frames if we don't have reference frames */ if(s->last_picture_ptr==NULL && (s->pict_type==AV_PICTURE_TYPE_B || s->dropable)) return get_consumed_bytes(s, buf_size); +#if FF_API_HURRY_UP + /* skip b frames if we are in a hurry */ + if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return get_consumed_bytes(s, buf_size); +#endif if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) return get_consumed_bytes(s, buf_size); +#if FF_API_HURRY_UP + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); +#endif if(s->next_p_frame_damaged){ if(s->pict_type==AV_PICTURE_TYPE_B) @@ -681,7 +701,7 @@ frame_end: int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3); int startcode_found=0; - if(buf_size - current_pos > 5){ + if(buf_size - current_pos > 7){ int i; for(i=current_pos; is; 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}; @@ -131,7 +131,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ if((h->left_samples_available&0x8080) != 0x8080){ mode= left[ mode ]; - if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred + 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){ @@ -183,20 +183,28 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_l i-= RS; } - if(i>=length-1){ //no escaped 0 - *dst_length= length; - *consumed= length+1; //+1 for the header - return src; - } - bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data - av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE); + si=h->rbsp_buffer_size[bufidx]; + av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE+MAX_MBPAIR_SIZE); dst= h->rbsp_buffer[bufidx]; + if(si != h->rbsp_buffer_size[bufidx]) + memset(dst + length, 0, FF_INPUT_BUFFER_PADDING_SIZE+MAX_MBPAIR_SIZE); if (dst == NULL){ return NULL; } + if(i>=length-1){ //no escaped 0 + *dst_length= length; + *consumed= length+1; //+1 for the header + if(h->s.avctx->flags2 & CODEC_FLAG2_FAST){ + return src; + }else{ + memcpy(dst, src, length); + return dst; + } + } + //printf("decoding esc\n"); memcpy(dst, src, i); si=di=i; @@ -997,8 +1005,12 @@ static av_cold void common_init(H264Context *h){ s->height = s->avctx->height; s->codec_id= s->avctx->codec->id; - ff_h264dsp_init(&h->h264dsp, 8); - ff_h264_pred_init(&h->hpc, s->codec_id, 8); + s->avctx->bits_per_raw_sample = 8; + + ff_h264dsp_init(&h->h264dsp, + s->avctx->bits_per_raw_sample); + ff_h264_pred_init(&h->hpc, s->codec_id, + s->avctx->bits_per_raw_sample); h->dequant_coeff_pps= -1; s->unrestricted_mv=1; @@ -1010,17 +1022,20 @@ static av_cold void common_init(H264Context *h){ memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t)); } -int ff_h264_decode_extradata(H264Context *h) +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) { AVCodecContext *avctx = h->s.avctx; - if(avctx->extradata[0] == 1){ + if(!buf || size <= 0) + return -1; + + if(buf[0] == 1){ int i, cnt, nalsize; - unsigned char *p = avctx->extradata; + const unsigned char *p = buf; h->is_avc = 1; - if(avctx->extradata_size < 7) { + if(size < 7) { av_log(avctx, AV_LOG_ERROR, "avcC too short\n"); return -1; } @@ -1032,6 +1047,8 @@ int ff_h264_decode_extradata(H264Context *h) p += 6; for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; + if(nalsize > size - (p-buf)) + return -1; if(decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); return -1; @@ -1042,6 +1059,8 @@ int ff_h264_decode_extradata(H264Context *h) cnt = *(p++); // Number of pps for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; + if(nalsize > size - (p-buf)) + return -1; if (decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i); return -1; @@ -1049,10 +1068,10 @@ int ff_h264_decode_extradata(H264Context *h) p += nalsize; } // Now store right nal length size, that will be use to parse all other nals - h->nal_length_size = (avctx->extradata[4] & 0x03) + 1; + h->nal_length_size = (buf[4] & 0x03) + 1; } else { h->is_avc = 0; - if(decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0) + if(decode_nal_units(h, buf, size) < 0) return -1; } return 0; @@ -1096,7 +1115,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){ } if(avctx->extradata_size > 0 && avctx->extradata && - ff_h264_decode_extradata(h)) + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size)) return -1; if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames < h->sps.num_reorder_frames){ @@ -1165,7 +1184,10 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex memcpy(&h->s + 1, &h1->s + 1, sizeof(H264Context) - sizeof(MpegEncContext)); //copy all fields after MpegEnc memset(h->sps_buffers, 0, sizeof(h->sps_buffers)); memset(h->pps_buffers, 0, sizeof(h->pps_buffers)); - ff_h264_alloc_tables(h); + if (ff_h264_alloc_tables(h) < 0) { + av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n"); + return AVERROR(ENOMEM); + } context_init(h); for(i=0; i<2; i++){ @@ -1403,7 +1425,7 @@ static void decode_postinit(H264Context *h, int setup_finished){ pics = 0; while(h->delayed_pic[pics]) pics++; - assert(pics <= MAX_DELAYED_PIC_COUNT); + av_assert0(pics <= MAX_DELAYED_PIC_COUNT); h->delayed_pic[pics++] = cur; if(cur->reference == 0) @@ -1682,7 +1704,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, int mb_ty uint64_t tr_high; if(dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED){ const int topright_avail= (h->topright_samples_available<mb_y || linesize <= block_offset[i]); if(!topright_avail){ if (pixel_shift) { tr_high= ((uint16_t*)ptr)[3 - linesize/2]*0x0001000100010001ULL; @@ -1848,15 +1870,30 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i tmp_y[j] = get_bits(&gb, bit_depth); } if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - for (i = 0; i < 8; i++) { - uint16_t *tmp_cb = (uint16_t*)(dest_cb + i*uvlinesize); - for (j = 0; j < 8; j++) - tmp_cb[j] = get_bits(&gb, bit_depth); - } - for (i = 0; i < 8; i++) { - uint16_t *tmp_cr = (uint16_t*)(dest_cr + i*uvlinesize); - for (j = 0; j < 8; j++) - tmp_cr[j] = get_bits(&gb, bit_depth); + if (!h->sps.chroma_format_idc) { + for (i = 0; i < 8; i++) { + uint16_t *tmp_cb = (uint16_t*)(dest_cb + i*uvlinesize); + for (j = 0; j < 8; j++) { + tmp_cb[j] = 1 << (bit_depth - 1); + } + } + for (i = 0; i < 8; i++) { + uint16_t *tmp_cr = (uint16_t*)(dest_cr + i*uvlinesize); + for (j = 0; j < 8; j++) { + tmp_cr[j] = 1 << (bit_depth - 1); + } + } + } else { + for (i = 0; i < 8; i++) { + uint16_t *tmp_cb = (uint16_t*)(dest_cb + i*uvlinesize); + for (j = 0; j < 8; j++) + tmp_cb[j] = get_bits(&gb, bit_depth); + } + for (i = 0; i < 8; i++) { + uint16_t *tmp_cr = (uint16_t*)(dest_cr + i*uvlinesize); + for (j = 0; j < 8; j++) + tmp_cr[j] = get_bits(&gb, bit_depth); + } } } } else { @@ -1864,9 +1901,16 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i memcpy(dest_y + i* linesize, h->mb + i*8, 16); } if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - for (i=0; i<8; i++) { - memcpy(dest_cb+ i*uvlinesize, h->mb + 128 + i*4, 8); - memcpy(dest_cr+ i*uvlinesize, h->mb + 160 + i*4, 8); + if (!h->sps.chroma_format_idc) { + for (i = 0; i < 8; i++) { + memset(dest_cb + i*uvlinesize, 128, 8); + memset(dest_cr + i*uvlinesize, 128, 8); + } + } else { + for (i = 0; i < 8; i++) { + memcpy(dest_cb + i*uvlinesize, h->mb + 128 + i*4, 8); + memcpy(dest_cr + i*uvlinesize, h->mb + 160 + i*4, 8); + } } } } @@ -2173,7 +2217,11 @@ static void implicit_weight_table(H264Context *h, int field){ } if(field < 0){ - cur_poc = s->current_picture_ptr->poc; + if (s->picture_structure == PICT_FRAME) { + cur_poc = s->current_picture_ptr->poc; + } else { + cur_poc = s->current_picture_ptr->field_poc[s->picture_structure - 1]; + } if( h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF && h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2*cur_poc){ h->use_weight= 0; @@ -2198,15 +2246,17 @@ static void implicit_weight_table(H264Context *h, int field){ for(ref0=ref_start; ref0 < ref_count0; ref0++){ int poc0 = h->ref_list[0][ref0].poc; for(ref1=ref_start; ref1 < ref_count1; ref1++){ - int poc1 = h->ref_list[1][ref1].poc; - int td = av_clip(poc1 - poc0, -128, 127); - int w= 32; - if(td){ - int tb = av_clip(cur_poc - poc0, -128, 127); - int tx = (16384 + (FFABS(td) >> 1)) / td; - int dist_scale_factor = (tb*tx + 32) >> 8; - if(dist_scale_factor >= -64 && dist_scale_factor <= 128) - w = 64 - dist_scale_factor; + int w = 32; + if (!h->ref_list[0][ref0].long_ref && !h->ref_list[1][ref1].long_ref) { + int poc1 = h->ref_list[1][ref1].poc; + int td = av_clip(poc1 - poc0, -128, 127); + if(td){ + int tb = av_clip(cur_poc - poc0, -128, 127); + int tx = (16384 + (FFABS(td) >> 1)) / td; + int dist_scale_factor = (tb*tx + 32) >> 8; + if(dist_scale_factor >= -64 && dist_scale_factor <= 128) + w = 64 - dist_scale_factor; + } } if(field<0){ h->implicit_weight[ref0][ref1][0]= @@ -2233,7 +2283,7 @@ static void idr(H264Context *h){ static void flush_dpb(AVCodecContext *avctx){ H264Context *h= avctx->priv_data; int i; - for(i=0; idelayed_pic[i]) h->delayed_pic[i]->reference= 0; h->delayed_pic[i]= NULL; @@ -2488,7 +2538,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s->dropable= h->nal_ref_idc == 0; - if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc){ + /* FIXME: 2tap qpel isn't implemented for high bit depth. */ + if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc && !h->pixel_shift){ s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab; s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab; }else{ @@ -2566,16 +2617,23 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ else s->height= 16*s->mb_height - (4>>CHROMA444)*FFMIN(h->sps.crop_bottom, (8<avctx->width, 16) == s->width && + FFALIGN(s->avctx->height, 16) == s->height) { + s->width = s->avctx->width; + s->height = s->avctx->height; + } + if (s->context_initialized && ( s->width != s->avctx->width || s->height != s->avctx->height || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) { - if(h != h0) { + if(h != h0 || (HAVE_THREADS && h->s.avctx->active_thread_type & FF_THREAD_FRAME)) { av_log_missing_feature(s->avctx, "Width/height changing with threads is", 0); - return -1; // width / height changed during parallelized decoding + return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding } free_tables(h, 0); flush_dpb(s->avctx); MPV_common_end(s); + h->list_count = 0; } if (!s->context_initialized) { if (h != h0) { @@ -2637,7 +2695,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->prev_interlaced_frame = 1; init_scan_tables(h); - ff_h264_alloc_tables(h); + if (ff_h264_alloc_tables(h) < 0) { + av_log(h->s.avctx, AV_LOG_ERROR, "Could not allocate memory for h264\n"); + return AVERROR(ENOMEM); + } if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_SLICE)) { if (context_init(h) < 0) { @@ -2745,11 +2806,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s0->first_field = FIELD_PICTURE; } else { - if (h->nal_ref_idc && - s0->current_picture_ptr->reference && - s0->current_picture_ptr->frame_num != h->frame_num) { + if (s0->current_picture_ptr->frame_num != h->frame_num) { /* - * This and previous field were reference, but had + * This and previous field had * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference * purposes. @@ -2833,6 +2892,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[1]= h->pps.ref_count[1]; if(h->slice_type_nos != AV_PICTURE_TYPE_I){ + unsigned max= s->picture_structure == PICT_FRAME ? 15 : 31; + if(h->slice_type_nos == AV_PICTURE_TYPE_B){ h->direct_spatial_mv_pred= get_bits1(&s->gb); } @@ -2840,28 +2901,36 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(num_ref_idx_active_override_flag){ h->ref_count[0]= get_ue_golomb(&s->gb) + 1; - if(h->slice_type_nos==AV_PICTURE_TYPE_B) + if (h->ref_count[0] < 1) + return AVERROR_INVALIDDATA; + if (h->slice_type_nos == AV_PICTURE_TYPE_B) { h->ref_count[1]= get_ue_golomb(&s->gb) + 1; - - if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); - h->ref_count[0]= h->ref_count[1]= 1; - return -1; + if (h->ref_count[1] < 1) + return AVERROR_INVALIDDATA; } } + + if (h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); + h->ref_count[0] = h->ref_count[1] = 1; + return AVERROR_INVALIDDATA; + } + if(h->slice_type_nos == AV_PICTURE_TYPE_B) h->list_count= 2; else h->list_count= 1; }else - h->list_count= 0; + h->ref_count[1]= h->ref_count[0]= h->list_count= 0; if(!default_ref_list_done){ ff_h264_fill_default_ref_list(h); } - if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) + if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) { + h->ref_count[1]= h->ref_count[0]= 0; return -1; + } if(h->slice_type_nos!=AV_PICTURE_TYPE_I){ s->last_picture_ptr= &h->ref_list[0][0]; @@ -3303,8 +3372,8 @@ static void loop_filter(H264Context *h, int start_x, int end_x){ uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2; if(mb_y&1){ //FIXME move out of this function? dest_y -= s->linesize*15; - dest_cb-= s->uvlinesize*7; - dest_cr-= s->uvlinesize*7; + dest_cb-= s->uvlinesize*((8 << CHROMA444)-1); + dest_cr-= s->uvlinesize*((8 << CHROMA444)-1); } } else { linesize = h->mb_linesize = s->linesize; @@ -3487,7 +3556,9 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ return 0; }else{ - ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, + s->mb_x - 1, s->mb_y, + (AC_END|DC_END|MV_END)&part_mask); return -1; } @@ -3649,7 +3720,11 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ break; } - if(buf_index+3 >= buf_size) break; + + if (buf_index + 3 >= buf_size) { + buf_index = buf_size; + break; + } buf_index+=3; if(buf_index >= next_avc) continue; @@ -3667,7 +3742,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(ptr[dst_length - 1] == 0 && dst_length > 0) + while(dst_length > 0 && ptr[dst_length - 1] == 0) dst_length--; } bit_length= !dst_length ? 0 : (8*dst_length - ff_h264_decode_rbsp_trailing(h, ptr + dst_length - 1)); @@ -3690,15 +3765,23 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ switch (hx->nal_unit_type) { case NAL_SPS: case NAL_PPS: + nals_needed = nal_index; + break; case NAL_IDR_SLICE: case NAL_SLICE: - nals_needed = nal_index; + init_get_bits(&hx->s.gb, ptr, bit_length); + if (!get_ue_golomb(&hx->s.gb)) + nals_needed = nal_index; } continue; } //FIXME do not discard SEI id - if(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0) + if( +#if FF_API_HURRY_UP + (s->hurry_up == 1 && h->nal_ref_idc == 0) || +#endif + (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) continue; again: @@ -3735,6 +3818,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ } if(hx->redundant_pic_count==0 +#if FF_API_HURRY_UP + && hx->s.hurry_up < 5 +#endif && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=AV_PICTURE_TYPE_B) && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==AV_PICTURE_TYPE_I) @@ -3771,7 +3857,11 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ hx->inter_gb_ptr= &hx->inter_gb; if(hx->redundant_pic_count==0 && hx->intra_gb_ptr && hx->s.data_partitioning + && s->current_picture_ptr && s->context_initialized +#if FF_API_HURRY_UP + && s->hurry_up < 5 +#endif && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=AV_PICTURE_TYPE_B) && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==AV_PICTURE_TYPE_I) @@ -3786,13 +3876,26 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ init_get_bits(&s->gb, ptr, bit_length); ff_h264_decode_seq_parameter_set(h); - if (s->flags& CODEC_FLAG_LOW_DELAY || - (h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames)) - s->low_delay=1; + if (s->flags & CODEC_FLAG_LOW_DELAY || + (h->sps.bitstream_restriction_flag && + !h->sps.num_reorder_frames)) { + if (s->avctx->has_b_frames > 1 || h->delayed_pic[0]) + av_log(avctx, AV_LOG_WARNING, "Delayed frames seen " + "reenabling low delay requires a codec " + "flush.\n"); + else + s->low_delay = 1; + } if(avctx->has_b_frames < 2) avctx->has_b_frames= !s->low_delay; + if (h->sps.bit_depth_luma != h->sps.bit_depth_chroma) { + av_log_missing_feature(s->avctx, + "Different bit depth between chroma and luma", 1); + return AVERROR_PATCHWELCOME; + } + if (avctx->bits_per_raw_sample != h->sps.bit_depth_luma) { if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) { avctx->bits_per_raw_sample = h->sps.bit_depth_luma; @@ -3910,7 +4013,11 @@ static int decode_frame(AVCodecContext *avctx, } if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){ - if (avctx->skip_frame >= AVDISCARD_NONREF) + if (avctx->skip_frame >= AVDISCARD_NONREF +#if FF_API_HURRY_UP + || s->hurry_up +#endif + ) return 0; av_log(avctx, AV_LOG_ERROR, "no frame!\n"); return -1; diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 7bad91b215..62a4ae2ad0 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -53,6 +53,8 @@ #define MAX_DELAYED_PIC_COUNT 16 +#define MAX_MBPAIR_SIZE (256*1024) // a tighter bound could be calculated if someone cares about a few bytes + /* Compiling in interlaced support reduces the speed * of progressive decoding by about 2%. */ #define ALLOW_INTERLACE @@ -99,7 +101,7 @@ */ #define DELAYED_PIC_REF 4 -#define QP_MAX_NUM (51 + 2*6) // The maximum supported qp +#define QP_MAX_NUM (51 + 4*6) // The maximum supported qp /* NAL unit types */ enum { @@ -225,7 +227,7 @@ typedef struct PPS{ int transform_8x8_mode; ///< transform_8x8_mode_flag uint8_t scaling_matrix4[6][16]; uint8_t scaling_matrix8[6][64]; - uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table + uint8_t chroma_qp_table[2][QP_MAX_NUM+1]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table int chroma_qp_diff; }PPS; @@ -507,7 +509,7 @@ typedef struct H264Context{ int cabac_init_idc; /** - * @defgroup multithreading Members for slice based multithreading + * @name Members for slice based multithreading * @{ */ struct H264Context *thread_context[MAX_THREADS]; @@ -582,7 +584,7 @@ typedef struct H264Context{ }H264Context; -extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1]; ///< One chroma qp table for each supported bit depth (8, 9, 10). +extern const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1]; ///< One chroma qp table for each possible bit depth (8-12). /** * Decode SEI @@ -656,12 +658,12 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h); /** * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode); +int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma); void ff_h264_write_back_intra_pred_mode(H264Context *h); void ff_h264_hl_decode_mb(H264Context *h); int ff_h264_frame_start(H264Context *h); -int ff_h264_decode_extradata(H264Context *h); +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size); av_cold int ff_h264_decode_init(AVCodecContext *avctx); av_cold int ff_h264_decode_end(AVCodecContext *avctx); av_cold void ff_h264_decode_init_vlc(void); @@ -1068,7 +1070,7 @@ static void fill_decode_caches(H264Context *h, int mb_type){ AV_ZERO32(h->mv_cache [list][scan8[0] + 4 - 1*8]); h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; } - if(h->ref_cache[list][scan8[0] + 4 - 1*8] < 0){ + if(h->ref_cache[list][scan8[0] + 2 - 1*8] < 0 || h->ref_cache[list][scan8[0] + 4 - 1*8] < 0){ if(USES_LIST(topleft_type, list)){ const int b_xy = h->mb2b_xy [topleft_xy] + 3 + h->b_stride + (h->topleft_partition & 2*h->b_stride); const int b8_xy= 4*topleft_xy + 1 + (h->topleft_partition & 2); diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 3975a61699..c1f4f7c8ee 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1701,7 +1701,7 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT \ if( coeff_abs >= 15 ) { \ int j = 0; \ - while( get_cabac_bypass( CC ) ) { \ + while(get_cabac_bypass( CC ) && j<30) { \ j++; \ } \ \ @@ -1959,6 +1959,8 @@ decode_intra_mb: } // The pixels are stored in the same order as levels in h->mb array. + if ((int) (h->cabac.bytestream_end - ptr) < mb_size) + return -1; memcpy(h->mb, ptr, mb_size); ptr+=mb_size; ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); @@ -2003,14 +2005,14 @@ decode_intra_mb: ff_h264_write_back_intra_pred_mode(h); if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1; } else { - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode ); + h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode, 0 ); if( h->intra16x16_pred_mode < 0 ) return -1; } if(decode_chroma){ h->chroma_pred_mode_table[mb_xy] = pred_mode = decode_cabac_mb_chroma_pre_mode( h ); - pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode ); + pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode, 1 ); if( pred_mode < 0 ) return -1; h->chroma_pred_mode= pred_mode; } else { diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 0ddc430661..1a438cf7bc 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -238,17 +238,18 @@ static inline int pred_non_zero_count(H264Context *h, int n){ } static av_cold void init_cavlc_level_tab(void){ - int suffix_length, mask; + int suffix_length; unsigned int i; for(suffix_length=0; suffix_length<7; suffix_length++){ for(i=0; i<(1<>(LEVEL_TAB_BITS-prefix-1-suffix_length)) - (1<>1) ^ mask) - mask; if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){ + int level_code = (prefix << suffix_length) + + (i >> (av_log2(i) - suffix_length)) - (1 << suffix_length); + int mask = -(level_code&1); + level_code = (((2 + level_code) >> 1) ^ mask) - mask; cavlc_level_tab[suffix_length][i][0]= level_code; cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length; }else if(prefix + 1 <= LEVEL_TAB_BITS){ @@ -620,7 +621,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){ @@ -735,12 +736,12 @@ decode_intra_mb: if( ff_h264_check_intra4x4_pred_mode(h) < 0) return -1; }else{ - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode); + h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode, 0); if(h->intra16x16_pred_mode < 0) return -1; } if(decode_chroma){ - pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); + pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb), 1); if(pred_mode < 0) return -1; h->chroma_pred_mode= pred_mode; diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 34a4ff727f..4ebb60e41c 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -89,7 +89,8 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, for(j=start; jref_list[0][j].frame_num + (h->ref_list[0][j].reference&3) == poc){ int cur_ref= mbafi ? (j-16)^field : j; - map[list][2*old_ref + (rfield^field) + 16] = cur_ref; + if(ref1->mbaff) + map[list][2*old_ref + (rfield^field) + 16] = cur_ref; if(rfield == field || !interl) map[list][old_ref] = cur_ref; break; @@ -252,6 +253,10 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; b8_stride = 2+4*s->mb_stride; b4_stride *= 6; + if(IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])){ + mb_type_col[0] &= ~MB_TYPE_INTERLACED; + mb_type_col[1] &= ~MB_TYPE_INTERLACED; + } sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index fd1fb5f662..46abc54c49 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -393,10 +393,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u AV_WN64A(bS, 0x0003000300030003ULL); } else { if(!CABAC && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])){ - bS[0]= 1+((h->cbp_table[mbn_xy] & 4)||h->non_zero_count_cache[scan8[0]+0]); - bS[1]= 1+((h->cbp_table[mbn_xy] & 4)||h->non_zero_count_cache[scan8[0]+1]); - bS[2]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+2]); - bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]); + bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]); + bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]); + bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]); + bS[3]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+3]); }else{ const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 3*4; int i; @@ -635,7 +635,7 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint else{ bS[i] = 1 + !!(h->non_zero_count_cache[12+8*(i>>1)] | ((!h->pps.cabac && IS_8x8DCT(mbn_type)) ? - (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2)) + (h->cbp_table[mbn_xy] & (((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2) << 12)) : h->non_zero_count[mbn_xy][ off[i] ])); } @@ -663,19 +663,33 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0] ); filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1] ); if (chroma){ - filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] ); - filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] ); - filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] ); - filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] ); + if (CHROMA444) { + filter_mb_mbaff_edgev ( h, img_cb, uvlinesize, bS , 1, bqp[0] ); + filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1] ); + filter_mb_mbaff_edgev ( h, img_cr, uvlinesize, bS , 1, rqp[0] ); + filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1] ); + }else{ + filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] ); + filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] ); + filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] ); + filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] ); + } } }else{ filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0] ); filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1] ); if (chroma){ - filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] ); - filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] ); - filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] ); - filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] ); + if (CHROMA444) { + filter_mb_mbaff_edgev ( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] ); + filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] ); + filter_mb_mbaff_edgev ( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] ); + filter_mb_mbaff_edgev ( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] ); + }else{ + filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] ); + filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] ); + filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] ); + filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] ); + } } } } diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 080b6a93b5..0d6aeccdb2 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -251,7 +251,13 @@ static int h264_parse(AVCodecParserContext *s, h->got_first = 1; if (avctx->extradata_size) { h->s.avctx = avctx; - ff_h264_decode_extradata(h); + // must be done like in decoder, otherwise opening the parser, + // letting it create extradata and then closing and opening again + // will cause has_b_frames to be always set. + // Note that estimate_timings_from_pts does exactly this. + if (!avctx->has_b_frames) + h->s.low_delay = 1; + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size); } } diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index ddfe1d2c64..8f2aa62dfc 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -37,6 +37,9 @@ //#undef NDEBUG #include +#define MAX_LOG2_MAX_FRAME_NUM (12 + 4) +#define MIN_LOG2_MAX_FRAME_NUM 4 + static const AVRational pixel_aspect[17]={ {0, 1}, {1, 1}, @@ -70,7 +73,7 @@ static const AVRational pixel_aspect[17]={ QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\ QP(39,d), QP(39,d), QP(39,d), QP(39,d) -const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = { +const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1] = { { CHROMA_QP_TABLE_END(8) }, @@ -83,6 +86,19 @@ const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = { 6, 7, 8, 9, 10, 11, CHROMA_QP_TABLE_END(10) }, + { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + CHROMA_QP_TABLE_END(11) + }, + { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + 18,19,20,21, 22, 23, + CHROMA_QP_TABLE_END(12) + }, }; static const uint8_t default_scaling4[2][16]={ @@ -130,8 +146,8 @@ static inline int decode_hrd_parameters(H264Context *h, SPS *sps){ get_bits(&s->gb, 4); /* bit_rate_scale */ get_bits(&s->gb, 4); /* cpb_size_scale */ for(i=0; igb); /* bit_rate_value_minus1 */ - get_ue_golomb(&s->gb); /* cpb_size_value_minus1 */ + get_ue_golomb_long(&s->gb); /* bit_rate_value_minus1 */ + get_ue_golomb_long(&s->gb); /* cpb_size_value_minus1 */ get_bits1(&s->gb); /* cbr_flag */ } sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1; @@ -281,12 +297,12 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb if(is_sps || pps->transform_8x8_mode){ decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y - if(h->sps.chroma_format_idc == 3){ + if(sps->chroma_format_idc == 3){ decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]); // Intra, Cr decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]); // Intra, Cb } decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]); // Inter, Y - if(h->sps.chroma_format_idc == 3){ + if(sps->chroma_format_idc == 3){ decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]); // Inter, Cr decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]); // Inter, Cb } @@ -298,7 +314,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ MpegEncContext * const s = &h->s; int profile_idc, level_idc, constraint_set_flags = 0; unsigned int sps_id; - int i; + int i, log2_max_frame_num_minus4; SPS *sps; profile_idc= get_bits(&s->gb, 8); @@ -327,12 +343,27 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); sps->scaling_matrix_present = 0; - if(sps->profile_idc >= 100){ //high profile + if (sps->profile_idc == 100 || sps->profile_idc == 110 || + sps->profile_idc == 122 || sps->profile_idc == 244 || + sps->profile_idc == 44 || sps->profile_idc == 83 || + sps->profile_idc == 86 || sps->profile_idc == 118 || + sps->profile_idc == 128 || sps->profile_idc == 144) { sps->chroma_format_idc= get_ue_golomb_31(&s->gb); - if(sps->chroma_format_idc == 3) + if (sps->chroma_format_idc > 3U) { + av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc); + goto fail; + } else if(sps->chroma_format_idc == 3) { sps->residual_color_transform_flag = get_bits1(&s->gb); + } sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; + if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 12 || + sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 12 || + sps->bit_depth_luma != sps->bit_depth_chroma) { + av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n", + sps->bit_depth_luma, sps->bit_depth_chroma); + goto fail; + } sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ @@ -341,7 +372,16 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->bit_depth_chroma = 8; } - sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4; + log2_max_frame_num_minus4 = get_ue_golomb(&s->gb); + if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 || + log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) { + av_log(h->s.avctx, AV_LOG_ERROR, + "log2_max_frame_num_minus4 out of range (0-12): %d\n", + log2_max_frame_num_minus4); + return AVERROR_INVALIDDATA; + } + sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4; + sps->poc_type= get_ue_golomb_31(&s->gb); if(sps->poc_type == 0){ //FIXME #define @@ -365,7 +405,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ } sps->ref_frame_count= get_ue_golomb_31(&s->gb); - if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){ + if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){ av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); goto fail; } @@ -396,6 +436,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ #endif sps->crop= get_bits1(&s->gb); if(sps->crop){ + int crop_limit = sps->chroma_format_idc == 3 ? 16 : 8; sps->crop_left = get_ue_golomb(&s->gb); sps->crop_right = get_ue_golomb(&s->gb); sps->crop_top = get_ue_golomb(&s->gb); @@ -403,7 +444,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ if(sps->crop_left || sps->crop_top){ av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); } - if(sps->crop_right >= (8<crop_bottom >= (8<crop_right >= crop_limit || sps->crop_bottom >= crop_limit){ av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); } }else{ @@ -462,10 +503,14 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ unsigned int pps_id= get_ue_golomb(&s->gb); PPS *pps; const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8); + int bits_left; if(pps_id >= MAX_PPS_COUNT) { av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); return -1; + } else if (h->sps.bit_depth_luma > 10) { + av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma); + return AVERROR_PATCHWELCOME; } pps= av_mallocz(sizeof(PPS)); @@ -538,7 +583,9 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4)); memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8)); - if(get_bits_count(&s->gb) < bit_length){ + bits_left = bit_length - get_bits_count(&s->gb); + if (bits_left && (bits_left > 8 || + show_bits(&s->gb, bits_left) != 1 << (bits_left - 1))) { pps->transform_8x8_mode= get_bits1(&s->gb); decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 9554201522..063ac97955 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -301,7 +301,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ void ff_h264_fill_mbaff_ref_list(H264Context *h){ int list, i, j; - for(list=0; list<2; list++){ //FIXME try list_count + for(list=0; listlist_count; list++){ for(i=0; iref_count[list]; i++){ Picture *frame = &h->ref_list[list][i]; Picture *field = &h->ref_list[list][16+2*i]; @@ -678,7 +678,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ } 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_LONG2UNUSED && FIELD_PICTURE))){ + 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; } diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index 83f6f38691..2acdf47a2f 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -237,7 +237,6 @@ void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM * } /** * IDCT transforms the 16 dc values and dequantizes them. - * @param qp quantization parameter */ void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *p_output, DCTELEM *p_input, int qmul){ #define stride 16 diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c index f6533cf9ba..4917e0d3a0 100644 --- a/libavcodec/h264pred.c +++ b/libavcodec/h264pred.c @@ -40,7 +40,7 @@ #undef BIT_DEPTH static void pred4x4_vertical_vp8_c(uint8_t *src, const uint8_t *topright, int stride){ - const int lt= src[-1-1*stride]; + const unsigned lt = src[-1-1*stride]; LOAD_TOP_EDGE LOAD_TOP_RIGHT_EDGE uint32_t v = PACK_4U8((lt + 2*t0 + t1 + 2) >> 2, @@ -55,7 +55,7 @@ static void pred4x4_vertical_vp8_c(uint8_t *src, const uint8_t *topright, int st } static void pred4x4_horizontal_vp8_c(uint8_t *src, const uint8_t *topright, int stride){ - const int lt= src[-1-1*stride]; + const unsigned lt = src[-1-1*stride]; LOAD_LEFT_EDGE AV_WN32A(src+0*stride, ((lt + 2*l0 + l1 + 2) >> 2)*0x01010101); @@ -292,7 +292,7 @@ static void pred16x16_tm_vp8_c(uint8_t *src, int stride){ static void pred8x8_left_dc_rv40_c(uint8_t *src, int stride){ int i; - int dc0; + unsigned dc0; dc0=0; for(i=0;i<8; i++) @@ -307,7 +307,7 @@ static void pred8x8_left_dc_rv40_c(uint8_t *src, int stride){ static void pred8x8_top_dc_rv40_c(uint8_t *src, int stride){ int i; - int dc0; + unsigned dc0; dc0=0; for(i=0;i<8; i++) @@ -322,7 +322,7 @@ static void pred8x8_top_dc_rv40_c(uint8_t *src, int stride){ static void pred8x8_dc_rv40_c(uint8_t *src, int stride){ int i; - int dc0=0; + unsigned dc0 = 0; for(i=0;i<4; i++){ dc0+= src[-1+i*stride] + src[i-stride]; diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c index 3cd4463d76..153aabc5f2 100644 --- a/libavcodec/h264pred_template.c +++ b/libavcodec/h264pred_template.c @@ -120,28 +120,28 @@ static void FUNCC(pred4x4_129_dc)(uint8_t *_src, const uint8_t *topright, int _s #define LOAD_TOP_RIGHT_EDGE\ - const int av_unused t4= topright[0];\ - const int av_unused t5= topright[1];\ - const int av_unused t6= topright[2];\ - const int av_unused t7= topright[3];\ + const unsigned av_unused t4 = topright[0];\ + const unsigned av_unused t5 = topright[1];\ + const unsigned av_unused t6 = topright[2];\ + const unsigned av_unused t7 = topright[3];\ #define LOAD_DOWN_LEFT_EDGE\ - const int av_unused l4= src[-1+4*stride];\ - const int av_unused l5= src[-1+5*stride];\ - const int av_unused l6= src[-1+6*stride];\ - const int av_unused l7= src[-1+7*stride];\ + const unsigned av_unused l4 = src[-1+4*stride];\ + const unsigned av_unused l5 = src[-1+5*stride];\ + const unsigned av_unused l6 = src[-1+6*stride];\ + const unsigned av_unused l7 = src[-1+7*stride];\ #define LOAD_LEFT_EDGE\ - const int av_unused l0= src[-1+0*stride];\ - const int av_unused l1= src[-1+1*stride];\ - const int av_unused l2= src[-1+2*stride];\ - const int av_unused l3= src[-1+3*stride];\ + const unsigned av_unused l0 = src[-1+0*stride];\ + const unsigned av_unused l1 = src[-1+1*stride];\ + const unsigned av_unused l2 = src[-1+2*stride];\ + const unsigned av_unused l3 = src[-1+3*stride];\ #define LOAD_TOP_EDGE\ - const int av_unused t0= src[ 0-1*stride];\ - const int av_unused t1= src[ 1-1*stride];\ - const int av_unused t2= src[ 2-1*stride];\ - const int av_unused t3= src[ 3-1*stride];\ + const unsigned av_unused t0 = src[ 0-1*stride];\ + const unsigned av_unused t1 = src[ 1-1*stride];\ + const unsigned av_unused t2 = src[ 2-1*stride];\ + const unsigned av_unused t3 = src[ 3-1*stride];\ static void FUNCC(pred4x4_down_right)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; diff --git a/libavcodec/high_bit_depth.h b/libavcodec/high_bit_depth.h index 511cd00f3a..c0a6eafe89 100644 --- a/libavcodec/high_bit_depth.h +++ b/libavcodec/high_bit_depth.h @@ -1,3 +1,21 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + #include "dsputil.h" #ifndef BIT_DEPTH diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index 0f59421bb7..20589652ff 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -28,6 +28,7 @@ * huffyuv codec for libavcodec. */ +#include "libavutil/avassert.h" #include "avcodec.h" #include "get_bits.h" #include "put_bits.h" @@ -82,13 +83,15 @@ typedef struct HYuvContext{ DSPContext dsp; }HYuvContext; -static const unsigned char classic_shift_luma[] = { +#define classic_shift_luma_table_size 42 +static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, 69,68, 0 }; -static const unsigned char classic_shift_chroma[] = { +#define classic_shift_chroma_table_size 59 +static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 @@ -184,7 +187,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){ if(repeat==0) repeat= get_bits(gb, 8); //printf("%d %d\n", val, repeat); - if(i+repeat > 256) { + if(i+repeat > 256 || get_bits_left(gb) < 0) { av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n"); return -1; } @@ -281,12 +284,13 @@ static void generate_joint_tables(HYuvContext *s){ 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; @@ -308,18 +312,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){ @@ -343,6 +348,7 @@ static void generate_joint_tables(HYuvContext *s){ static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length){ GetBitContext gb; int i; + int ret; init_get_bits(&gb, src, length*8); @@ -353,7 +359,8 @@ static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length){ return -1; } free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); + if ((ret = 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); @@ -365,11 +372,12 @@ static int read_old_huffman_tables(HYuvContext *s){ #if 1 GetBitContext gb; int i; + int ret; - init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8); + init_get_bits(&gb, classic_shift_luma, classic_shift_luma_table_size*8); if(read_len_table(s->len[0], &gb)<0) return -1; - init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); + init_get_bits(&gb, classic_shift_chroma, classic_shift_chroma_table_size*8); if(read_len_table(s->len[1], &gb)<0) return -1; @@ -385,7 +393,8 @@ static int read_old_huffman_tables(HYuvContext *s){ for(i=0; i<3; i++){ free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); + 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); @@ -515,7 +524,7 @@ s->bgr32=1; } break; default: - assert(0); + return AVERROR_INVALIDDATA; } alloc_temp(s); diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c index 362ba3bde9..78ac77bf25 100644 --- a/libavcodec/idcinvideo.c +++ b/libavcodec/idcinvideo.c @@ -72,7 +72,6 @@ typedef struct IdcinContext { hnode huff_nodes[256][HUF_TOKENS*2]; int num_huff_nodes[256]; - uint32_t pal[256]; } IdcinContext; /* @@ -215,7 +214,7 @@ static int idcin_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; IdcinContext *s = avctx->priv_data; - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); + AVPaletteControl *palette_control = avctx->palctrl; s->buf = buf; s->size = buf_size; @@ -230,12 +229,13 @@ static int idcin_decode_frame(AVCodecContext *avctx, idcin_decode_vlcs(s); - if (pal) { - s->frame.palette_has_changed = 1; - memcpy(s->pal, pal, AVPALETTE_SIZE); - } /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4); + /* If palette changed inform application*/ + if (palette_control->palette_changed) { + palette_control->palette_changed = 0; + s->frame.palette_has_changed = 1; + } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 195ef10ac7..622bd4f020 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -176,7 +176,13 @@ static int extract_header(AVCodecContext *const avctx, const uint8_t *buf; unsigned buf_size; IffContext *s = avctx->priv_data; - int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + int palette_size; + + if (avctx->extradata_size < 2) { + av_log(avctx, AV_LOG_ERROR, "not enough extradata\n"); + return AVERROR_INVALIDDATA; + } + palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); if (avpkt) { int image_size; @@ -192,8 +198,6 @@ static int extract_header(AVCodecContext *const avctx, return AVERROR_INVALIDDATA; } } else { - if (avctx->extradata_size < 2) - return AVERROR_INVALIDDATA; buf = avctx->extradata; buf_size = bytestream_get_be16(&buf); if (buf_size <= 1 || palette_size < 0) { @@ -281,7 +285,12 @@ static av_cold int decode_init(AVCodecContext *avctx) int err; if (avctx->bits_per_coded_sample <= 8) { - int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + int palette_size; + + if (avctx->extradata_size >= 2) + palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + else + palette_size = 0; avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) || (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8; } else if (avctx->bits_per_coded_sample <= 32) { diff --git a/libavcodec/imc.c b/libavcodec/imc.c index f08efe46ec..bc1a6a9f3c 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -104,10 +104,15 @@ static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2]; static av_cold int imc_decode_init(AVCodecContext * avctx) { - int i, j; + int i, j, ret; IMCContext *q = avctx->priv_data; double r1, r2; + if (avctx->channels != 1) { + av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); + return AVERROR_PATCHWELCOME; + } + q->decoder_reset = 1; for(i = 0; i < BANDS; i++) @@ -156,7 +161,10 @@ static av_cold int imc_decode_init(AVCodecContext * avctx) } q->one_div_log2 = 1/log(2); - ff_fft_init(&q->fft, 7, 1); + if ((ret = ff_fft_init(&q->fft, 7, 1))) { + av_log(avctx, AV_LOG_INFO, "FFT init failed\n"); + return ret; + } dsputil_init(&q->dsp, avctx); avctx->sample_fmt = AV_SAMPLE_FMT_FLT; avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index 9aa584fa5c..9375b19e44 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -424,11 +424,40 @@ const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt) } #endif +#if LIBAVCODEC_VERSION_MAJOR < 53 +enum PixelFormat avcodec_get_pix_fmt(const char *name) +{ + return av_get_pix_fmt(name); +} + +void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt) +{ + av_get_pix_fmt_string(buf, buf_size, pix_fmt); +} +#endif + int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt) { return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL; } +#if LIBAVCODEC_VERSION_MAJOR < 53 +int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){ + return ff_set_systematic_pal2(pal, pix_fmt); +} + +int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width) +{ + return av_image_fill_linesizes(picture->linesize, pix_fmt, width); +} + +int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, + int height) +{ + return av_image_fill_pointers(picture->data, pix_fmt, height, ptr, picture->linesize); +} +#endif + int avpicture_fill(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, int width, int height) { @@ -470,6 +499,16 @@ int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, } } + switch (pix_fmt) { + case PIX_FMT_RGB8: + case PIX_FMT_BGR8: + case PIX_FMT_RGB4_BYTE: + case PIX_FMT_BGR4_BYTE: + case PIX_FMT_GRAY8: + // do not include palette for these pseudo-paletted formats + return size; + } + if (desc->flags & PIX_FMT_PAL) memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4); @@ -615,7 +654,8 @@ static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, /* find exact color match with smallest size */ dst_pix_fmt = PIX_FMT_NONE; min_dist = 0x7fffffff; - for(i = 0;i < PIX_FMT_NB; i++) { + /* test only the first 64 pixel formats to avoid undefined behaviour */ + for (i = 0; i < 64; i++) { if (pix_fmt_mask & (1ULL << i)) { loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; if (loss == 0) { @@ -663,6 +703,28 @@ enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelForma return dst_pix_fmt; } +#if LIBAVCODEC_VERSION_MAJOR < 53 +void ff_img_copy_plane(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + av_image_copy_plane(dst, dst_wrap, src, src_wrap, width, height); +} + +int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane) +{ + return av_image_get_linesize(pix_fmt, width, plane); +} + +void av_picture_data_copy(uint8_t *dst_data[4], int dst_linesize[4], + uint8_t *src_data[4], int src_linesize[4], + enum PixelFormat pix_fmt, int width, int height) +{ + av_image_copy(dst_data, dst_linesize, src_data, src_linesize, + pix_fmt, width, height); +} +#endif + void av_picture_copy(AVPicture *dst, const AVPicture *src, enum PixelFormat pix_fmt, int width, int height) { diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index f58804bab3..152b7cca6c 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -153,6 +153,13 @@ static int ir2_decode_frame(AVCodecContext *avctx, return -1; } + start = 48; /* hardcoded for now */ + + if (start >= buf_size) { + av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size); + return AVERROR_INVALIDDATA; + } + s->decode_delta = buf[18]; /* decide whether frame uses deltas or not */ @@ -160,9 +167,8 @@ static int ir2_decode_frame(AVCodecContext *avctx, for (i = 0; i < buf_size; i++) buf[i] = av_reverse[buf[i]]; #endif - start = 48; /* hardcoded for now */ - init_get_bits(&s->gb, buf + start, buf_size - start); + init_get_bits(&s->gb, buf + start, (buf_size - start) * 8); if (s->decode_delta) { /* intraframe */ ir2_decode_plane(s, avctx->width, avctx->height, diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index 4c6bfd66d1..1f454a32c2 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -76,6 +76,8 @@ typedef struct { int is_scalable; uint32_t lock_word; IVIPicConfig pic_conf; + + int gop_invalid; } IVI5DecContext; @@ -219,6 +221,10 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) } if (band->blk_size == 8) { + if(quant_mat >= 5){ + av_log(avctx, AV_LOG_ERROR, "quant_mat %d too large!\n", quant_mat); + return -1; + } band->intra_base = &ivi5_base_quant_8x8_intra[quant_mat][0]; band->inter_base = &ivi5_base_quant_8x8_inter[quant_mat][0]; band->intra_scale = &ivi5_scale_quant_8x8_intra[quant_mat][0]; @@ -335,8 +341,12 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) ctx->frame_num = get_bits(&ctx->gb, 8); if (ctx->frame_type == FRAMETYPE_INTRA) { - if (decode_gop_header(ctx, avctx)) - return -1; + ctx->gop_invalid = 1; + if (decode_gop_header(ctx, avctx)) { + av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n"); + return AVERROR_INVALIDDATA; + } + ctx->gop_invalid = 0; } if (ctx->frame_type != FRAMETYPE_NULL) { @@ -453,6 +463,16 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, ref_mb = tile->ref_mbs; offs = tile->ypos * band->pitch + tile->xpos; + if (!ref_mb && + ((band->qdelta_present && band->inherit_qdelta) || band->inherit_mv)) + return AVERROR_INVALIDDATA; + + if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { + av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches parameters %d\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return AVERROR_INVALIDDATA; + } + /* scale factor for motion vectors */ mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3); mv_x = mv_y = 0; @@ -603,8 +623,10 @@ static int decode_band(IVI5DecContext *ctx, int plane_num, tile->is_empty = get_bits1(&ctx->gb); if (tile->is_empty) { - ff_ivi_process_empty_tile(avctx, band, tile, + result = ff_ivi_process_empty_tile(avctx, band, tile, (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); + if (result < 0) + break; } else { tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); @@ -751,6 +773,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, "Error while decoding picture header: %d\n", result); return -1; } + if (ctx->gop_invalid) + return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); @@ -780,6 +804,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->release_buffer(avctx, &ctx->frame); ctx->frame.reference = 0; + avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); if (avctx->get_buffer(avctx, &ctx->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c index a011a9f597..0de163505c 100644 --- a/libavcodec/intelh263dec.c +++ b/libavcodec/intelh263dec.c @@ -65,8 +65,8 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s) s->pb_frame = get_bits1(&s->gb); if (format < 6) { - s->width = h263_format[format][0]; - s->height = h263_format[format][1]; + s->width = ff_h263_format[format][0]; + s->height = ff_h263_format[format][1]; s->avctx->sample_aspect_ratio.num = 12; s->avctx->sample_aspect_ratio.den = 11; } else { @@ -77,7 +77,7 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s) } if(get_bits(&s->gb, 2)) av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); - s->loop_filter = get_bits1(&s->gb); + s->loop_filter = get_bits1(&s->gb) * !s->avctx->lowres; if(get_bits1(&s->gb)) av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); if(get_bits1(&s->gb)) diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 7e26e1db7d..5c61af39e4 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -69,7 +69,6 @@ typedef struct IpvideoContext { int stride; int upper_motion_limit_offset; - uint32_t pal[256]; } IpvideoContext; #define CHECK_STREAM_PTR(stream_ptr, stream_end, n) \ @@ -962,7 +961,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s) if (!s->is_16bpp) { /* this is PAL8, so make the palette available */ - memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->current_frame.data[1], s->avctx->palctrl->palette, PALETTE_COUNT * 4); s->stride = s->current_frame.linesize[0]; s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */ @@ -1016,6 +1015,10 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx) s->is_16bpp = avctx->bits_per_coded_sample == 16; avctx->pix_fmt = s->is_16bpp ? PIX_FMT_RGB555 : PIX_FMT_PAL8; + if (!s->is_16bpp && s->avctx->palctrl == NULL) { + av_log(avctx, AV_LOG_ERROR, " Interplay video: palette expected.\n"); + return -1; + } dsputil_init(&s->dsp, avctx); @@ -1038,6 +1041,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; IpvideoContext *s = avctx->priv_data; + AVPaletteControl *palette_control = avctx->palctrl; /* compressed buffer needs to be large enough to at least hold an entire * decoding map */ @@ -1054,16 +1058,13 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, return -1; } - if (!s->is_16bpp) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - if (pal) { - s->current_frame.palette_has_changed = 1; - memcpy(s->pal, pal, AVPALETTE_SIZE); - } - } - ipvideo_decode_opcodes(s); + if (!s->is_16bpp && palette_control->palette_changed) { + palette_control->palette_changed = 0; + s->current_frame.palette_has_changed = 1; + } + *data_size = sizeof(AVFrame); *(AVFrame*)data = s->current_frame; diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index b1e67231fd..72e036a95d 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -100,7 +100,7 @@ static VLC cbpc_b_vlc; /* init vlcs */ /* XXX: find a better solution to handle static init */ -void h263_decode_init_vlc(MpegEncContext *s) +void ff_h263_decode_init_vlc(MpegEncContext *s) { static int done = 0; @@ -117,18 +117,18 @@ void h263_decode_init_vlc(MpegEncContext *s) &ff_h263_cbpy_tab[0][1], 2, 1, &ff_h263_cbpy_tab[0][0], 2, 1, 64); INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 538); + &ff_mvtab[0][1], 2, 1, + &ff_mvtab[0][0], 2, 1, 538); init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - init_rl(&rl_intra_aic, ff_h263_static_rl_table_store[1]); + init_rl(&ff_rl_intra_aic, ff_h263_static_rl_table_store[1]); INIT_VLC_RL(ff_h263_rl_inter, 554); - INIT_VLC_RL(rl_intra_aic, 554); + INIT_VLC_RL(ff_rl_intra_aic, 554); INIT_VLC_STATIC(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15, - &h263_mbtype_b_tab[0][1], 2, 1, - &h263_mbtype_b_tab[0][0], 2, 1, 80); + &ff_h263_mbtype_b_tab[0][1], 2, 1, + &ff_h263_mbtype_b_tab[0][0], 2, 1, 80); INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4, - &cbpc_b_tab[0][1], 2, 1, - &cbpc_b_tab[0][0], 2, 1, 8); + &ff_cbpc_b_tab[0][1], 2, 1, + &ff_cbpc_b_tab[0][0], 2, 1, 8); } } @@ -268,7 +268,7 @@ int ff_h263_resync(MpegEncContext *s){ return -1; } -int h263_decode_motion(MpegEncContext * s, int pred, int f_code) +int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code) { int code, val, sign, shift, l; code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); @@ -379,16 +379,16 @@ static void preview_obmc(MpegEncContext *s){ if ((cbpc & 16) == 0) { s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ - mot_val= h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= mx; @@ -397,16 +397,16 @@ static void preview_obmc(MpegEncContext *s){ } else { s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ mot_val[0] = mx; @@ -430,7 +430,7 @@ static void h263_decode_dquant(MpegEncContext *s){ if(s->modified_quant){ if(get_bits1(&s->gb)) - s->qscale= modified_quant_tab[get_bits1(&s->gb)][ s->qscale ]; + s->qscale= ff_modified_quant_tab[get_bits1(&s->gb)][ s->qscale ]; else s->qscale= get_bits(&s->gb, 5); }else @@ -448,7 +448,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, scan_table = s->intra_scantable.permutated; if (s->h263_aic && s->mb_intra) { - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; i = 0; if (s->ac_pred) { if (s->h263_aic_dir) @@ -537,7 +537,7 @@ retry: if (i >= 64){ if(s->alt_inter_vlc && rl == &ff_h263_rl_inter && !s->mb_intra){ //Looks like a hack but no, it's the way it is supposed to work ... - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; i = 0; s->gb= gb; s->dsp.clear_block(block); @@ -554,7 +554,7 @@ retry: } not_coded: if (s->mb_intra && s->h263_aic) { - h263_pred_acdc(s, block, n); + ff_h263_pred_acdc(s, block, n); i = 63; } s->block_last_index[n] = i; @@ -653,11 +653,11 @@ int ff_h263_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (mx >= 0xffff) return -1; @@ -665,7 +665,7 @@ int ff_h263_decode_mb(MpegEncContext *s, if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); if (my >= 0xffff) return -1; @@ -678,18 +678,18 @@ int ff_h263_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (mx >= 0xffff) return -1; if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); if (my >= 0xffff) return -1; s->mv[0][i][0] = mx; @@ -761,11 +761,11 @@ int ff_h263_decode_mb(MpegEncContext *s, //FIXME UMV if(USES_LIST(mb_type, 0)){ - int16_t *mot_val= h263_pred_motion(s, 0, 0, &mx, &my); + int16_t *mot_val= ff_h263_pred_motion(s, 0, 0, &mx, &my); s->mv_dir = MV_DIR_FORWARD; - mx = h263_decode_motion(s, mx, 1); - my = h263_decode_motion(s, my, 1); + mx = ff_h263_decode_motion(s, mx, 1); + my = ff_h263_decode_motion(s, my, 1); s->mv[0][0][0] = mx; s->mv[0][0][1] = my; @@ -774,11 +774,11 @@ int ff_h263_decode_mb(MpegEncContext *s, } if(USES_LIST(mb_type, 1)){ - int16_t *mot_val= h263_pred_motion(s, 0, 1, &mx, &my); + int16_t *mot_val= ff_h263_pred_motion(s, 0, 1, &mx, &my); s->mv_dir |= MV_DIR_BACKWARD; - mx = h263_decode_motion(s, mx, 1); - my = h263_decode_motion(s, my, 1); + mx = ff_h263_decode_motion(s, mx, 1); + my = ff_h263_decode_motion(s, my, 1); s->mv[1][0][0] = mx; s->mv[1][0][1] = my; @@ -829,8 +829,8 @@ intra: } while(pb_mv_count--){ - h263_decode_motion(s, 0, 1); - h263_decode_motion(s, 0, 1); + ff_h263_decode_motion(s, 0, 1); + ff_h263_decode_motion(s, 0, 1); } /* decode each block */ @@ -864,7 +864,7 @@ end: } /* most is hardcoded. should extend to handle all h263 streams */ -int h263_decode_picture_header(MpegEncContext *s) +int ff_h263_decode_picture_header(MpegEncContext *s) { int format, width, height, i; uint32_t startcode; @@ -916,8 +916,8 @@ int h263_decode_picture_header(MpegEncContext *s) if (format != 7 && format != 6) { s->h263_plus = 0; /* H.263v1 */ - width = h263_format[format][0]; - height = h263_format[format][1]; + width = ff_h263_format[format][0]; + height = ff_h263_format[format][1]; if (!width) return -1; @@ -961,6 +961,8 @@ int h263_decode_picture_header(MpegEncContext *s) s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */ s->loop_filter= get_bits1(&s->gb); s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter; + if(s->avctx->lowres) + s->loop_filter = 0; s->h263_slice_structured= get_bits1(&s->gb); if (get_bits1(&s->gb) != 0) { @@ -1024,8 +1026,8 @@ int h263_decode_picture_header(MpegEncContext *s) s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info]; } } else { - width = h263_format[format][0]; - height = h263_format[format][1]; + width = ff_h263_format[format][0]; + height = ff_h263_format[format][1]; s->avctx->sample_aspect_ratio= (AVRational){12,11}; } if ((width == 0) || (height == 0)) diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c index 320f82a83f..934da923cf 100644 --- a/libavcodec/ituh263enc.c +++ b/libavcodec/ituh263enc.c @@ -102,7 +102,7 @@ av_const int ff_h263_aspect_to_info(AVRational aspect){ return FF_ASPECT_EXTENDED; } -void h263_encode_picture_header(MpegEncContext * s, int picture_number) +void ff_h263_encode_picture_header(MpegEncContext * s, int picture_number) { int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref; int best_clock_code=1; @@ -141,7 +141,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 1, 0); /* camera off */ put_bits(&s->pb, 1, 0); /* freeze picture release off */ - format = ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height); + format = ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format), s->width, s->height); if (!s->h263_plus) { /* H.263v1 */ put_bits(&s->pb, 3, format); @@ -247,7 +247,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) /** * Encode a group of blocks header. */ -void h263_encode_gob_header(MpegEncContext * s, int mb_line) +void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line) { put_bits(&s->pb, 17, 1); /* GBSC */ @@ -333,7 +333,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) } else { i = 0; if (s->h263_aic && s->mb_intra) - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; if(s->alt_inter_vlc && !s->mb_intra){ int aic_vlc_bits=0; @@ -353,14 +353,14 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) if(level<0) level= -level; code = get_rl_index(rl, last, run, level); - aic_code = get_rl_index(&rl_intra_aic, last, run, level); + aic_code = get_rl_index(&ff_rl_intra_aic, last, run, level); inter_vlc_bits += rl->table_vlc[code][1]+1; - aic_vlc_bits += rl_intra_aic.table_vlc[aic_code][1]+1; + aic_vlc_bits += ff_rl_intra_aic.table_vlc[aic_code][1]+1; if (code == rl->n) { inter_vlc_bits += 1+6+8-1; } - if (aic_code == rl_intra_aic.n) { + if (aic_code == ff_rl_intra_aic.n) { aic_vlc_bits += 1+6+8-1; wrong_pos += run + 1; }else @@ -370,7 +370,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) } i = 0; if(aic_vlc_bits < inter_vlc_bits && wrong_pos > 63) - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; } } @@ -454,9 +454,9 @@ static void h263p_encode_umotion(MpegEncContext * s, int val) } } -void h263_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) +void ff_h263_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) { int cbpc, cbpy, i, cbp, pred_x, pred_y; int16_t pred_dc; @@ -500,7 +500,7 @@ void h263_encode_mb(MpegEncContext * s, } /* motion vectors: 16x16 mode */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (!s->umvplus) { ff_h263_encode_motion_vector(s, motion_x - pred_x, @@ -527,7 +527,7 @@ void h263_encode_mb(MpegEncContext * s, for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ - h263_pred_motion(s, i, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0]; motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1]; @@ -561,7 +561,7 @@ void h263_encode_mb(MpegEncContext * s, if(i<4) scale= s->y_dc_scale; else scale= s->c_dc_scale; - pred_dc = h263_pred_dc(s, i, &dc_ptr[i]); + pred_dc = ff_h263_pred_dc(s, i, &dc_ptr[i]); level -= pred_dc; /* Quant */ if (level >= 0) @@ -662,7 +662,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) if (val == 0) { /* zero vector */ code = 0; - put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); + put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); } else { bit_size = f_code - 1; range = 1 << bit_size; @@ -677,7 +677,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) code = (val >> bit_size) + 1; bits = val & (range - 1); - put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); + put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); } @@ -693,7 +693,7 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) for(mv=-MAX_MV; mv<=MAX_MV; mv++){ int len; - if(mv==0) len= mvtab[0][1]; + if(mv==0) len= ff_mvtab[0][1]; else{ int val, bit_size, code; @@ -705,9 +705,9 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) val--; code = (val >> bit_size) + 1; if(code<33){ - len= mvtab[code][1] + 1 + bit_size; + len= ff_mvtab[code][1] + 1 + bit_size; }else{ - len= mvtab[32][1] + av_log2(code>>5) + 2 + bit_size; + len= ff_mvtab[32][1] + av_log2(code>>5) + 2 + bit_size; } } @@ -769,7 +769,7 @@ static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_t } } -void h263_encode_init(MpegEncContext *s) +void ff_h263_encode_init(MpegEncContext *s) { static int done = 0; @@ -777,9 +777,9 @@ void h263_encode_init(MpegEncContext *s) done = 1; init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - init_rl(&rl_intra_aic, ff_h263_static_rl_table_store[1]); + init_rl(&ff_rl_intra_aic, ff_h263_static_rl_table_store[1]); - init_uni_h263_rl_tab(&rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); + init_uni_h263_rl_tab(&ff_rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); init_uni_h263_rl_tab(&ff_h263_rl_inter , NULL, uni_h263_inter_rl_len); init_mv_penalty_and_fcode(s); diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 7f14a89f33..dae8b6aef2 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -123,6 +123,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, 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); @@ -136,9 +140,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc, &huff_tab->cust_tab, 0); if (result) { + huff_tab->cust_desc.num_rows = 0; // reset faulty description av_log(avctx, AV_LOG_ERROR, "Error while initializing custom vlc table!\n"); - return -1; + return result; } } huff_tab->tab = &huff_tab->cust_tab; @@ -207,14 +212,15 @@ int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) band->width = b_width; band->height = b_height; band->pitch = width_aligned; - band->bufs[0] = av_malloc(buf_size); - band->bufs[1] = av_malloc(buf_size); + band->aheight = height_aligned; + band->bufs[0] = av_mallocz(buf_size); + band->bufs[1] = av_mallocz(buf_size); if (!band->bufs[0] || !band->bufs[1]) return AVERROR(ENOMEM); /* allocate the 3rd band buffer for scalability mode */ if (cfg->luma_bands > 1) { - band->bufs[2] = av_malloc(buf_size); + band->bufs[2] = av_mallocz(buf_size); if (!band->bufs[2]) return AVERROR(ENOMEM); } @@ -377,6 +383,21 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) mv_x >>= 1; mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ } + if (mb->type) { + int dmv_x, dmv_y, cx, cy; + + dmv_x = mb->mv_x >> band->is_halfpel; + dmv_y = mb->mv_y >> band->is_halfpel; + cx = mb->mv_x & band->is_halfpel; + cy = mb->mv_y & band->is_halfpel; + + if ( mb->xpos + dmv_x < 0 + || mb->xpos + dmv_x + band->mb_size + cx > band->pitch + || mb->ypos + dmv_y < 0 + || mb->ypos + dmv_y + band->mb_size + cy > band->aheight) { + return AVERROR_INVALIDDATA; + } + } } for (blk = 0; blk < num_blocks; blk++) { @@ -389,6 +410,11 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) } if (cbp & 1) { /* block coded ? */ + if (!band->scan) { + av_log(NULL, 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 */ @@ -469,7 +495,7 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) return 0; } -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, +int ff_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; @@ -480,6 +506,13 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); + if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { + av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches " + "parameters %d in ivi_process_empty_tile()\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return AVERROR_INVALIDDATA; + } + offs = tile->ypos * band->pitch + tile->xpos; mb = tile->mbs; ref_mb = tile->ref_mbs; @@ -560,6 +593,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, dst += band->pitch; } } + + return 0; } diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index 10cca26045..654ee6f2bc 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -132,6 +132,7 @@ typedef struct { int band_num; ///< band number int width; int height; + int aheight; ///< aligned band height const uint8_t *data_ptr; ///< ptr to the first byte of the band data int data_size; ///< size of the band data int16_t *buf; ///< pointer to the output buffer for this band @@ -324,7 +325,7 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile); * @param[in] tile pointer to the tile descriptor * @param[in] mv_scale scaling factor for motion vectors */ -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, +int ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVITile *tile, int32_t mv_scale); /** diff --git a/libavcodec/j2k_dwt.c b/libavcodec/j2k_dwt.c index 9ba770ad83..48aa33735e 100644 --- a/libavcodec/j2k_dwt.c +++ b/libavcodec/j2k_dwt.c @@ -321,6 +321,8 @@ int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int int i, j, lev = decomp_levels, maxlen, b[2][2]; + if ((unsigned)decomp_levels >= FF_DWT_MAX_DECLVLS) + return AVERROR_INVALIDDATA; s->ndeclevels = decomp_levels; s->type = type; diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c index 73af6a73df..2b6929d18e 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "bytestream.h" #include "j2k.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #define JP2_SIG_TYPE 0x6A502020 @@ -283,6 +284,10 @@ static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c) c->log2_cblk_width = bytestream_get_byte(&s->buf) + 2; // cblk width c->log2_cblk_height = bytestream_get_byte(&s->buf) + 2; // cblk height + if (c->log2_cblk_width > 6 || c->log2_cblk_height > 6) { + return AVERROR_PATCHWELCOME; + } + c->cblk_style = bytestream_get_byte(&s->buf); if (c->cblk_style != 0){ // cblk style av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); @@ -359,7 +364,7 @@ static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q) if (q->quantsty == J2K_QSTY_NONE){ n -= 3; - if (s->buf_end - s->buf < n) + if (s->buf_end - s->buf < n || 32*3 < n) return AVERROR(EINVAL); for (i = 0; i < n; i++) q->expn[i] = bytestream_get_byte(&s->buf) >> 3; @@ -376,7 +381,7 @@ static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q) } } else{ n = (n - 3) >> 1; - if (s->buf_end - s->buf < n) + if (s->buf_end - s->buf < n || 32*3 < n) return AVERROR(EINVAL); for (i = 0; i < n; i++){ x = bytestream_get_be16(&s->buf); @@ -421,6 +426,10 @@ static uint8_t get_sot(J2kDecoderContext *s) return AVERROR(EINVAL); s->curtileno = bytestream_get_be16(&s->buf); ///< Isot + if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){ + s->curtileno=0; + return AVERROR(EINVAL); + } s->buf += 4; ///< Psot (ignored) @@ -695,6 +704,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)); @@ -961,18 +973,20 @@ static int decode_codestream(J2kDecoderContext *s) static int jp2_find_codestream(J2kDecoderContext *s) { - int32_t atom_size; + uint32_t atom_size; int found_codestream = 0, search_range = 10; // skip jpeg2k signature atom s->buf += 12; - while(!found_codestream && search_range) { + while(!found_codestream && search_range && s->buf_end - s->buf >= 8) { atom_size = AV_RB32(s->buf); if(AV_RB32(s->buf + 4) == JP2_CODESTREAM) { found_codestream = 1; s->buf += 8; } else { + if (s->buf_end - s->buf < atom_size) + return 0; s->buf += atom_size; search_range--; } @@ -1005,7 +1019,8 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); // check if the image is in jp2 format - if((AV_RB32(s->buf) == 12) && (AV_RB32(s->buf + 4) == JP2_SIG_TYPE) && + if(s->buf_end - s->buf >= 12 && + (AV_RB32(s->buf) == 12) && (AV_RB32(s->buf + 4) == JP2_SIG_TYPE) && (AV_RB32(s->buf + 8) == JP2_SIG_VALUE)) { if(!jp2_find_codestream(s)) { av_log(avctx, AV_LOG_ERROR, "couldn't find jpeg2k codestream atom\n"); diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h index 28c75248be..2c21f774e8 100644 --- a/libavcodec/jpegls.h +++ b/libavcodec/jpegls.h @@ -86,6 +86,8 @@ static inline void ff_jpegls_downscale_state(JLSState *state, int Q){ } static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){ + if(FFABS(err) > 0xFFFF) + return -0x10000; state->A[Q] += FFABS(err); err *= state->twonear; state->B[Q] += err; diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 7278e020da..628fed1836 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -203,6 +203,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; diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index f4941992f6..238cfffe7d 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -143,6 +143,10 @@ static int decode_frame(AVCodecContext *avctx, buf += 5; if (video_size) { + if(video_size < 0) { + av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size); + return AVERROR_INVALIDDATA; + } if (avctx->reget_buffer(avctx, &s->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -150,7 +154,7 @@ static int decode_frame(AVCodecContext *avctx, if (video_type == 0 || video_type == 1) { GetBitContext gb; - init_get_bits(&gb, buf, FFMIN(video_size, buf_end - buf)); + init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf)); for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index c364cfc593..264efa2a29 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -30,19 +30,26 @@ typedef struct { AVCodecContext *avctx; - AVFrame pic; - uint16_t *prev, *cur; + AVFrame prev, cur; } KgvContext; +static void decode_flush(AVCodecContext *avctx) +{ + KgvContext * const c = avctx->priv_data; + + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); +} + static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; KgvContext * const c = avctx->priv_data; - int offsets[7]; + int offsets[8]; uint16_t *out, *prev; int outcnt = 0, maxcnt; - int w, h, i; + int w, h, i, res; if (avpkt->size < 2) return -1; @@ -54,22 +61,25 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (av_image_check_size(w, h, 0, avctx)) return -1; - if (w != avctx->width || h != avctx->height) + if (w != avctx->width || h != avctx->height) { + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); avcodec_set_dimensions(avctx, w, h); + } maxcnt = w * h; - out = av_realloc(c->cur, w * h * 2); - if (!out) - return -1; - c->cur = out; + c->cur.reference = 3; + if ((res = avctx->get_buffer(avctx, &c->cur)) < 0) + return res; + out = (uint16_t *) c->cur.data[0]; + if (c->prev.data[0]) { + prev = (uint16_t *) c->prev.data[0]; + } else { + prev = NULL; + } - prev = av_realloc(c->prev, w * h * 2); - if (!prev) - return -1; - c->prev = prev; - - for (i = 0; i < 7; i++) + for (i = 0; i < 8; i++) offsets[i] = -1; while (outcnt < maxcnt && buf_end - 2 > buf) { @@ -80,6 +90,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac out[outcnt++] = code; // rgb555 pixel coded directly } else { int count; + int inp_off; uint16_t *inp; if ((code & 0x6000) == 0x6000) { @@ -101,7 +112,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (maxcnt - start < count) break; - inp = prev + start; + if (!prev) { + av_log(avctx, AV_LOG_ERROR, + "Frame reference does not exist\n"); + break; + } + + inp = prev; + inp_off = start; } else { // copy from earlier in this frame int offset = (code & 0x1FFF) + 1; @@ -119,27 +137,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (outcnt < offset) break; - inp = out + outcnt - offset; + inp = out; + inp_off = outcnt - offset; } if (maxcnt - outcnt < count) break; - for (i = 0; i < count; i++) + for (i = inp_off; i < count + inp_off; i++) { out[outcnt++] = inp[i]; + } } } if (outcnt - maxcnt) av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - c->pic.data[0] = (uint8_t *)c->cur; - c->pic.linesize[0] = w * 2; - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; + *(AVFrame*)data = c->cur; - FFSWAP(uint16_t *, c->cur, c->prev); + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); + FFSWAP(AVFrame, c->cur, c->prev); return avpkt->size; } @@ -150,30 +169,25 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; - avcodec_get_frame_defaults(&c->pic); + avctx->flags |= CODEC_FLAG_EMU_EDGE; return 0; } static av_cold int decode_end(AVCodecContext *avctx) { - KgvContext * const c = avctx->priv_data; - - av_freep(&c->cur); - av_freep(&c->prev); - + decode_flush(avctx); return 0; } AVCodec ff_kgv1_decoder = { - "kgv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_KGV1, - sizeof(KgvContext), - decode_init, - NULL, - decode_end, - decode_frame, - .max_lowres = 1, + .name = "kgv1", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_KGV1, + .priv_data_size = sizeof(KgvContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .flush = decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), }; diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index aa2aaace6c..793c6f1010 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -33,6 +33,7 @@ #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 #define KMVC_METHOD 0x0F +#define MAX_PALSIZE 256 /* * Decoder context @@ -43,7 +44,7 @@ typedef struct KmvcContext { int setpal; int palsize; - uint32_t pal[256]; + uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; uint8_t *frm0, *frm1; } KmvcContext; @@ -57,17 +58,21 @@ typedef struct BitBuf { #define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++; -#define kmvc_getbit(bb, src, res) {\ +#define kmvc_getbit(bb, src, src_end, res) {\ res = 0; \ if (bb.bitbuf & (1 << bb.bits)) res = 1; \ bb.bits--; \ if(bb.bits == -1) { \ + if (src >= src_end) { \ + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); \ + return AVERROR_INVALIDDATA; \ + } \ bb.bitbuf = *src++; \ bb.bits = 7; \ } \ } -static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) +static int kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h) { BitBuf bb; int res, val; @@ -75,13 +80,18 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int bx, by; int l0x, l1x, l0y, l1y; int mx, my; + const uint8_t *src_end = src + src_size; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 8x8 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; @@ -89,14 +99,22 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 4x4 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block from already decoded place + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = val & 0xF; my = val >> 4; @@ -108,16 +126,24 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 2x2 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block from already decoded place + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = val & 0xF; my = val >> 4; @@ -140,9 +166,11 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, } } } + + return 0; } -static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) +static int kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h) { BitBuf bb; int res, val; @@ -150,15 +178,20 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int bx, by; int l0x, l1x, l0y, l1y; int mx, my; + const uint8_t *src_end = src + src_size; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 8x8 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; @@ -171,14 +204,22 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 4x4 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; @@ -190,16 +231,24 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 2x2 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; @@ -222,6 +271,8 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, } } } + + return 0; } static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) @@ -233,7 +284,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa int i; int header; int blocksize; - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (ctx->pic.data[0]) avctx->release_buffer(avctx, &ctx->pic); @@ -265,6 +315,13 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa ctx->pic.pict_type = AV_PICTURE_TYPE_P; } + /* if palette has been changed, copy it from palctrl */ + if (ctx->avctx->palctrl && ctx->avctx->palctrl->palette_changed) { + memcpy(ctx->pal, ctx->avctx->palctrl->palette, AVPALETTE_SIZE); + ctx->setpal = 1; + ctx->avctx->palctrl->palette_changed = 0; + } + if (header & KMVC_PALETTE) { ctx->pic.palette_has_changed = 1; // palette starts from index 1 and has 127 entries @@ -273,11 +330,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa } } - if (pal) { - ctx->pic.palette_has_changed = 1; - memcpy(ctx->pal, pal, AVPALETTE_SIZE); - } - if (ctx->setpal) { ctx->setpal = 0; ctx->pic.palette_has_changed = 1; @@ -299,10 +351,10 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa memcpy(ctx->cur, ctx->prev, 320 * 200); break; case 3: - kmvc_decode_intra_8x8(ctx, buf, avctx->width, avctx->height); + kmvc_decode_intra_8x8(ctx, buf, buf_size, avctx->width, avctx->height); break; case 4: - kmvc_decode_inter_8x8(ctx, buf, avctx->width, avctx->height); + kmvc_decode_inter_8x8(ctx, buf, buf_size, avctx->width, avctx->height); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD); @@ -364,6 +416,10 @@ static av_cold int decode_init(AVCodecContext * avctx) c->palsize = 127; } else { c->palsize = AV_RL16(avctx->extradata + 10); + if (c->palsize >= MAX_PALSIZE) { + av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n"); + return AVERROR_INVALIDDATA; + } } if (avctx->extradata_size == 1036) { // palette in extradata @@ -373,6 +429,9 @@ static av_cold int decode_init(AVCodecContext * avctx) src += 4; } c->setpal = 1; + if (c->avctx->palctrl) { + c->avctx->palctrl->palette_changed = 0; + } } avcodec_get_frame_defaults(&c->pic); diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 02d3533b0c..059d7f7893 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -322,6 +322,11 @@ static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, output_zeros: if (l->zeros_rem) { count = FFMIN(l->zeros_rem, width - i); + if (end - dst < count) { + av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n"); + return AVERROR_INVALIDDATA; + } + memset(dst, 0, count); l->zeros_rem -= count; dst += count; diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 57735ac6ff..8f753ea088 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -223,8 +223,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac len = mszh_dlen; } break; - case COMP_MSZH_NOCOMP: + case COMP_MSZH_NOCOMP: { + int bppx2; + switch (c->imgtype) { + case IMGTYPE_YUV111: + case IMGTYPE_RGB24: + bppx2 = 6; + break; + case IMGTYPE_YUV422: + case IMGTYPE_YUV211: + bppx2 = 4; + break; + case IMGTYPE_YUV411: + case IMGTYPE_YUV420: + bppx2 = 3; + break; + default: + bppx2 = 0; // will error out below + break; + } + if (len < ((width * height * bppx2) >> 1)) + return AVERROR_INVALIDDATA; break; + } default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); return -1; @@ -456,7 +477,7 @@ static av_cold int decode_init(AVCodecContext *avctx) avcodec_get_frame_defaults(&c->pic); if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); - return 1; + return AVERROR_INVALIDDATA; } /* Check codec type */ @@ -505,7 +526,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); - return 1; + return AVERROR_INVALIDDATA; } /* Detect compression method */ @@ -522,7 +543,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); - return 1; + return AVERROR_INVALIDDATA; } break; #if CONFIG_ZLIB_DECODER @@ -540,7 +561,7 @@ static av_cold int decode_init(AVCodecContext *avctx) default: if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) { av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); - return 1; + return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); } @@ -548,14 +569,14 @@ static av_cold int decode_init(AVCodecContext *avctx) #endif default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); - return 1; + return AVERROR_INVALIDDATA; } /* Allocate decompression buffer */ if (c->decomp_size) { if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; + return AVERROR(ENOMEM); } } @@ -581,7 +602,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); av_freep(&c->decomp_buf); - return 1; + return AVERROR_INVALIDDATA; } } #endif diff --git a/libavcodec/libaacplus.c b/libavcodec/libaacplus.c new file mode 100644 index 0000000000..a5ededbf39 --- /dev/null +++ b/libavcodec/libaacplus.c @@ -0,0 +1,134 @@ +/* + * Interface to libaacplus for aac+ (sbr+ps) encoding + * Copyright (c) 2010 tipok + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Interface to libaacplus for aac+ (sbr+ps) encoding. + */ + +#include "avcodec.h" +#include + +typedef struct aacPlusAudioContext { + aacplusEncHandle aacplus_handle; +} aacPlusAudioContext; + +static av_cold int aacPlus_encode_init(AVCodecContext *avctx) +{ + aacPlusAudioContext *s = avctx->priv_data; + aacplusEncConfiguration *aacplus_cfg; + unsigned long samples_input, max_bytes_output; + + /* number of channels */ + if (avctx->channels < 1 || avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); + return -1; + } + + s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, + avctx->channels, + &samples_input, &max_bytes_output); + if(!s->aacplus_handle) { + av_log(avctx, AV_LOG_ERROR, "can't open encoder\n"); + return -1; + } + + /* check aacplus version */ + aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle); + + /* put the options in the configuration struct */ + if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) { + av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile); + aacplusEncClose(s->aacplus_handle); + return -1; + } + + aacplus_cfg->bitRate = avctx->bit_rate; + aacplus_cfg->bandWidth = avctx->cutoff; + aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER); + aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT; + if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) { + av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n"); + return -1; + } + + avctx->frame_size = samples_input / avctx->channels; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + /* Set decoder specific info */ + avctx->extradata_size = 0; + if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { + + unsigned char *buffer = NULL; + unsigned long decoder_specific_info_size; + + if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer, + &decoder_specific_info_size) == 1) { + avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); + avctx->extradata_size = decoder_specific_info_size; + memcpy(avctx->extradata, buffer, avctx->extradata_size); + } +#undef free + free(buffer); +#define free please_use_av_free + } + return 0; +} + +static int aacPlus_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + aacPlusAudioContext *s = avctx->priv_data; + int bytes_written; + + bytes_written = aacplusEncEncode(s->aacplus_handle, + data, + avctx->frame_size * avctx->channels, + frame, + buf_size); + + return bytes_written; +} + +static av_cold int aacPlus_encode_close(AVCodecContext *avctx) +{ + aacPlusAudioContext *s = avctx->priv_data; + + av_freep(&avctx->coded_frame); + av_freep(&avctx->extradata); + + aacplusEncClose(s->aacplus_handle); + return 0; +} + +AVCodec ff_libaacplus_encoder = { + "libaacplus", + AVMEDIA_TYPE_AUDIO, + CODEC_ID_AAC, + sizeof(aacPlusAudioContext), + aacPlus_encode_init, + aacPlus_encode_frame, + aacPlus_encode_close, + .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"), +}; diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 1f76f82d55..073cf4498d 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -141,18 +141,25 @@ static int libgsm_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int out_size = avctx->frame_size * av_get_bytes_per_sample(avctx->sample_fmt); + + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + *data_size = 0; /* In case of error */ if(buf_size < avctx->block_align) return -1; switch(avctx->codec_id) { case CODEC_ID_GSM: if(gsm_decode(avctx->priv_data,buf,data)) return -1; - *data_size = GSM_FRAME_SIZE*sizeof(int16_t); break; case CODEC_ID_GSM_MS: if(gsm_decode(avctx->priv_data,buf,data) || gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; - *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; } + + *data_size = out_size; return avctx->block_align; } diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c new file mode 100644 index 0000000000..79a9fb0760 --- /dev/null +++ b/libavcodec/libspeexenc.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2009 by Xuggle Incorporated. All rights reserved. + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include + +typedef struct { + SpeexBits bits; + void *enc_state; + SpeexHeader header; +} LibSpeexEncContext; + + +static av_cold int libspeex_encode_init(AVCodecContext *avctx) +{ + LibSpeexEncContext *s = (LibSpeexEncContext*)avctx->priv_data; + const SpeexMode *mode; + + if ((avctx->sample_fmt != SAMPLE_FMT_S16 && avctx->sample_fmt != SAMPLE_FMT_FLT) || + avctx->sample_rate <= 0 || + avctx->channels <= 0 || + avctx->channels > 2) + { + av_log(avctx, AV_LOG_ERROR, "Unsupported sample format, rate, or channels for speex"); + return -1; + } + + if (avctx->sample_rate <= 8000) + mode = &speex_nb_mode; + else if (avctx->sample_rate <= 16000) + mode = &speex_wb_mode; + else + mode = &speex_uwb_mode; + + speex_bits_init(&s->bits); + s->enc_state = speex_encoder_init(mode); + if (!s->enc_state) + { + av_log(avctx, AV_LOG_ERROR, "could not initialize speex encoder"); + return -1; + } + + // initialize the header + speex_init_header(&s->header, avctx->sample_rate, + avctx->channels, mode); + + // TODO: It'd be nice to support VBR here, but + // I'm uncertain what AVCodecContext options to use + // to signal whether to turn it on. + if (avctx->flags & CODEC_FLAG_QSCALE) { + spx_int32_t quality = 0; + // Map global_quality's mpeg 1/2/4 scale into Speex's 0-10 scale + if (avctx->global_quality > FF_LAMBDA_MAX) + quality = 0; // lowest possible quality + else + quality = (spx_int32_t)((FF_LAMBDA_MAX-avctx->global_quality)*10.0/FF_LAMBDA_MAX); + speex_encoder_ctl(s->enc_state, SPEEX_SET_QUALITY, &quality); + } else { + // default to CBR + if (avctx->bit_rate > 0) + speex_encoder_ctl(s->enc_state, SPEEX_SET_BITRATE, &avctx->bit_rate); + // otherwise just take the default quality setting + } + // reset the bit-rate to the actual bit rate speex will use + speex_encoder_ctl(s->enc_state, SPEEX_GET_BITRATE, &s->header.bitrate); + avctx->bit_rate = s->header.bitrate; + + // get the actual sample rate + speex_encoder_ctl(s->enc_state, SPEEX_GET_SAMPLING_RATE, &s->header.rate); + avctx->sample_rate = s->header.rate; + + // get the frame-size. To align with FLV, we're going to put 2 frames + // per packet. If someone can tell me how to make this configurable + // from the avcodec contents, I'll mod this so it's not hard-coded. + // but without this, FLV files with speex data won't play correctly + // in flash player 10. + speex_encoder_ctl(s->enc_state, SPEEX_GET_FRAME_SIZE, &s->header.frame_size); + s->header.frames_per_packet = 2; // Need for FLV container support + avctx->frame_size = s->header.frame_size*s->header.frames_per_packet; + + // and we'll put a speex header packet into extradata so that muxers + // can use it. + avctx->extradata = speex_header_to_packet(&s->header, &avctx->extradata_size); + return 0; +} + +static av_cold int libspeex_encode_frame( + AVCodecContext *avctx, uint8_t *frame, + int buf_size, void *data) +{ + LibSpeexEncContext *s = (LibSpeexEncContext*)avctx->priv_data; + int i = 0; + + if (!data) + // nothing to flush + return 0; + + speex_bits_reset(&s->bits); + for(i = 0; i < s->header.frames_per_packet; i++) + { + if (avctx->sample_fmt == SAMPLE_FMT_FLT) + { + if (avctx->channels == 2) { + speex_encode_stereo( + (float*)data+i*s->header.frame_size, + s->header.frame_size, + &s->bits); + } + speex_encode(s->enc_state, + (float*)data+i*s->header.frame_size, &s->bits); + } else { + if (avctx->channels == 2) { + speex_encode_stereo_int( + (spx_int16_t*)data+i*s->header.frame_size, + s->header.frame_size, + &s->bits); + } + speex_encode_int(s->enc_state, + (spx_int16_t*)data+i*s->header.frame_size, &s->bits); + } + } + // put in a terminator so this will fit in a OGG or FLV packet + speex_bits_insert_terminator(&s->bits); + + if (buf_size >= speex_bits_nbytes(&s->bits)) { + return speex_bits_write(&s->bits, frame, buf_size); + } else { + av_log(avctx, AV_LOG_ERROR, "output buffer too small"); + return -1; + } +} + +static av_cold int libspeex_encode_close(AVCodecContext *avctx) +{ + LibSpeexEncContext *s = (LibSpeexEncContext*)avctx->priv_data; + + speex_bits_destroy(&s->bits); + speex_encoder_destroy(s->enc_state); + s->enc_state = 0; + if (avctx->extradata) + speex_header_free(avctx->extradata); + avctx->extradata = 0; + avctx->extradata_size = 0; + + return 0; +} + +AVCodec ff_libspeex_encoder = { + "libspeex", + AVMEDIA_TYPE_AUDIO, + CODEC_ID_SPEEX, + sizeof(LibSpeexEncContext), + libspeex_encode_init, + libspeex_encode_frame, + libspeex_encode_close, + 0, + .capabilities = CODEC_CAP_DELAY, + .supported_samplerates = (const int[]){8000, 16000, 32000, 0}, + .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_FLT,SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex Encoder"), +}; diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c index bc219ded9b..4e05268439 100644 --- a/libavcodec/libvorbis.c +++ b/libavcodec/libvorbis.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "bytestream.h" #include "vorbis.h" +#include "libavutil/mathematics.h" #undef NDEBUG #include diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index f5c942e0fc..990badb87b 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -31,6 +31,7 @@ #include "avcodec.h" #include "libavutil/base64.h" #include "libavutil/opt.h" +#include "libavutil/mathematics.h" /** * Portion of struct vpx_codec_cx_pkt from vpx_encoder.h. @@ -480,8 +481,8 @@ static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size, break; case VPX_CODEC_STATS_PKT: { struct vpx_fixed_buf *stats = &ctx->twopass_stats; - stats->buf = av_realloc(stats->buf, - stats->sz + pkt->data.twopass_stats.sz); + stats->buf = av_realloc_f(stats->buf, 1, + stats->sz + pkt->data.twopass_stats.sz); if (!stats->buf) { av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n"); return AVERROR(ENOMEM); diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index cc5b9837f8..6477f3fbe0 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -70,9 +70,14 @@ static int encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, /* Write the SEI as part of the first frame. */ if (x4->sei_size > 0 && nnal > 0) { + if (x4->sei_size > size) { + av_log(ctx, AV_LOG_ERROR, "Error: nal buffer is too small\n"); + return -1; + } memcpy(p, x4->sei, x4->sei_size); p += x4->sei_size; x4->sei_size = 0; + // why is x4->sei not freed? } for (i = 0; i < nnal; i++){ @@ -83,6 +88,11 @@ static int encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, memcpy(x4->sei, nals[i].p_payload, nals[i].i_payload); continue; } + if (nals[i].i_payload > (size - (p - buf))) { + // return only complete nals which fit in buf + av_log(ctx, AV_LOG_ERROR, "Error: nal buffer is too small\n"); + break; + } memcpy(p, nals[i].p_payload, nals[i].i_payload); p += nals[i].i_payload; } @@ -91,13 +101,14 @@ static int encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, } static int X264_frame(AVCodecContext *ctx, uint8_t *buf, - int bufsize, void *data) + int orig_bufsize, void *data) { X264Context *x4 = ctx->priv_data; AVFrame *frame = data; x264_nal_t *nal; int nnal, i; x264_picture_t pic_out; + int bufsize; x264_picture_init( &x4->pic ); x4->pic.img.i_csp = X264_CSP_I420; @@ -128,6 +139,7 @@ static int X264_frame(AVCodecContext *ctx, uint8_t *buf, } do { + bufsize = orig_bufsize; if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) return -1; diff --git a/libavcodec/libxvidff.c b/libavcodec/libxvidff.c index 9b5c17c59d..c09d9a8ff8 100644 --- a/libavcodec/libxvidff.c +++ b/libavcodec/libxvidff.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" #include "libxvid_internal.h" #if !HAVE_MKSTEMP #include @@ -528,6 +529,7 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) { if( x->twopassbuffer != NULL ) { av_free(x->twopassbuffer); av_free(x->old_twopassbuffer); + avctx->stats_out = NULL; } av_free(x->twopassfile); av_free(x->intra_matrix); diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 5f863433ef..3d5c490686 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -59,6 +59,9 @@ read_header: s->restart_count = 0; s->mjpb_skiptosod = 0; + if (buf_end - buf_ptr >= 1 << 28) + return AVERROR_INVALIDDATA; + init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); skip_bits(&hgb, 32); /* reserved zeros */ @@ -66,7 +69,7 @@ read_header: if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) { av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); - return 0; + return AVERROR_INVALIDDATA; } field_size = get_bits_long(&hgb, 32); /* field size */ @@ -109,8 +112,8 @@ read_header: av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); if (sos_offs) { -// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8); - init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8); + init_get_bits(&s->gb, buf_ptr + sos_offs, + 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; ff_mjpeg_decode_sos(s, NULL, NULL); @@ -142,7 +145,7 @@ read_header: picture->quality*= FF_QP2LAMBDA; } - return buf_ptr - buf; + return buf_size; } AVCodec ff_mjpegb_decoder = { diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 02c66f504b..9323d53db6 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -212,16 +212,16 @@ 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; /* 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) s->rct=1; //FIXME ugly + if(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; } @@ -241,7 +241,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (nb_components <= 0 || nb_components > MAX_COMPONENTS) return -1; - if (s->ls && !(s->bits <= 8 || nb_components == 1)){ + if (s->ls && !(bits <= 8 || nb_components == 1)){ av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n"); return -1; } @@ -274,11 +274,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* if different size, realloc/alloc picture */ /* XXX: also check h_count and v_count */ - if (width != s->width || height != s->height) { + if ( width != s->width || height != s->height + || bits != s->bits + ) { av_freep(&s->qscale_table); s->width = width; s->height = height; + s->bits = bits; s->interlaced = 0; /* test interlaced mode */ @@ -318,8 +321,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) case 0x11111100: if(s->rgb){ s->avctx->pix_fmt = PIX_FMT_BGRA; - }else + }else{ s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + } assert(s->nb_components==3); break; case 0x11000000: @@ -327,21 +332,27 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) break; case 0x12111100: s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV440P : PIX_FMT_YUVJ440P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; case 0x21111100: s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; case 0x22111100: s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; default: av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); return -1; } if(s->ls){ - if(s->nb_components > 1) + if(s->nb_components == 3) { s->avctx->pix_fmt = PIX_FMT_RGB24; - else if(s->bits <= 8) + } else if (s->nb_components != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of components %d\n", s->nb_components); + return AVERROR_PATCHWELCOME; + } else if (s->bits <= 8) s->avctx->pix_fmt = PIX_FMT_GRAY8; else s->avctx->pix_fmt = PIX_FMT_GRAY16; @@ -848,19 +859,28 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, i if(s->interlaced && s->bottom_field) block_offset += linesize[c] >> 1; - ptr = data[c] + block_offset; - if(!s->progressive) { + 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); + 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], - s->quant_matrixes[ s->quant_index[c] ]) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); - return -1; - } - s->dsp.idct_put(ptr, linesize[c], s->block); + s->dsp.clear_block(s->block); + if (decode_block(s, s->block, i, + s->dc_index[i], s->ac_index[i], + s->quant_matrixes[s->quant_index[c]]) < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "error y=%d x=%d\n", mb_y, mb_x); + return -1; + } + if (ptr) { + s->dsp.idct_put(ptr, linesize[c], s->block); + } } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + (h * mb_x + x); @@ -881,14 +901,19 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, i } } - if (s->restart_interval && show_bits(&s->gb, 8) == 0xFF){/* skip RSTn */ - --s->restart_count; + if (s->restart_interval) --s->restart_count; + i= 8+((-get_bits_count(&s->gb))&7); + if (s->restart_interval && show_bits(&s->gb, i) == (1<gb); align_get_bits(&s->gb); while(show_bits(&s->gb, 8) == 0xFF) skip_bits(&s->gb, 8); - skip_bits(&s->gb, 8); - for (i=0; ilast_dc[i] = 1024; + if((get_bits(&s->gb, 8)&0xF8) == 0xD0){ + for (i=0; ilast_dc[i] = 1024; + }else{ + skip_bits_long(&s->gb, pos - get_bits_count(&s->gb)); + } } } } @@ -1164,6 +1189,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"); skip_bits(&s->gb, 16); /* version ? */ @@ -1172,17 +1199,27 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) skip_bits(&s->gb, 16); /* unknwon always 0? */ switch( get_bits(&s->gb, 8)){ case 1: - s->rgb= 1; - s->pegasus_rct=0; + rgb = 1; + pegasus_rct = 0; break; case 2: - s->rgb= 1; - s->pegasus_rct=1; + rgb = 1; + pegasus_rct = 1; break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace\n"); } + len -= 9; + if (s->got_picture) + if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) { + av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n"); + goto out; + } + + s->rgb = rgb; + s->pegasus_rct = pegasus_rct; + goto out; } diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index b13d0795cd..baae9a321d 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -950,7 +950,12 @@ static int output_data_internal(MLPDecodeContext *m, unsigned int substr, int32_t *data_32 = (int32_t*) data; int16_t *data_16 = (int16_t*) data; - if (*data_size < (s->max_channel + 1) * s->blockpos * (is32 ? 4 : 2)) + if (m->avctx->channels != s->max_matrix_channel + 1) { + av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n"); + return AVERROR_INVALIDDATA; + } + + if (*data_size < m->avctx->channels * s->blockpos * (is32 ? 4 : 2)) return -1; for (i = 0; i < s->blockpos; i++) { diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index 707ddc5f7e..0136bf8a9e 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -105,7 +105,7 @@ static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const if (color) { memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length); - if (half_vert) + if (half_vert && y + half_vert < s->avctx->height) memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length); } x+= run_length; diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index c12ebf4c7c..82979a540c 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -52,7 +52,7 @@ static inline int sad_hpel_motion_search(MpegEncContext * s, int src_index, int ref_index, int size, int h); -static inline int update_map_generation(MotionEstContext *c) +static inline unsigned update_map_generation(MotionEstContext *c) { c->map_generation+= 1<<(ME_MAP_MV_BITS*2); if(c->map_generation==0){ @@ -1040,7 +1040,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, /* intra / predictive decision */ pix = c->src[0][0]; sum = s->dsp.pix_sum(pix, s->linesize); - varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500; + varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)sum*sum)>>8) + 500; pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8; @@ -1202,7 +1202,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){ intra_score= varc - 500; }else{ - int mean= (sum+128)>>8; + unsigned mean = (sum+128)>>8; mean*= 0x01010101; for(i=0; i<16; i++){ diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c index 461e85932b..dd1a6de1b3 100644 --- a/libavcodec/motion_est_template.c +++ b/libavcodec/motion_est_template.c @@ -158,9 +158,8 @@ static int hpel_motion_search(MpegEncContext * s, const int b= score_map[(index+(1<penalty_factor; -#if 1 - int key; - int map_generation= c->map_generation; + unsigned key; + unsigned map_generation= c->map_generation; #ifndef NDEBUG uint32_t *map= c->map; #endif @@ -172,7 +171,6 @@ static int hpel_motion_search(MpegEncContext * s, assert(map[(index+1)&(ME_MAP_SIZE-1)] == key); key= ((my)<sub_penalty_factor; - const int map_generation= c->map_generation; + const unsigned map_generation = c->map_generation; const int subpel_quality= c->avctx->me_subpel_quality; uint32_t *map= c->map; me_cmp_func cmpf, chroma_cmpf; @@ -497,7 +495,7 @@ static int qpel_motion_search(MpegEncContext * s, #define CHECK_MV(x,y)\ {\ - const int key= ((y)<= xmin);\ assert((x) <= xmax);\ @@ -525,7 +523,7 @@ static int qpel_motion_search(MpegEncContext * s, #define CHECK_MV_DIR(x,y,new_dir)\ {\ - const int key= ((y)<map_generation; + unsigned map_generation = c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; { /* ensure that the best point is in the MAP as h/qpel refinement needs it */ - const int key= (best[1]<map_generation; + unsigned map_generation = c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; @@ -646,7 +644,7 @@ static int hex_search(MpegEncContext * s, int *best, int dmin, me_cmp_func cmpf, chroma_cmpf; LOAD_COMMON LOAD_COMMON2 - int map_generation= c->map_generation; + unsigned map_generation = c->map_generation; int x,y,d; const int dec= dia_size & (dia_size-1); @@ -680,7 +678,7 @@ static int l2s_dia_search(MpegEncContext * s, int *best, int dmin, me_cmp_func cmpf, chroma_cmpf; LOAD_COMMON LOAD_COMMON2 - int map_generation= c->map_generation; + unsigned map_generation = c->map_generation; int x,y,i,d; int dia_size= c->dia_size&0xFF; const int dec= dia_size & (dia_size-1); @@ -718,7 +716,7 @@ static int umh_search(MpegEncContext * s, int *best, int dmin, me_cmp_func cmpf, chroma_cmpf; LOAD_COMMON LOAD_COMMON2 - int map_generation= c->map_generation; + unsigned map_generation = c->map_generation; int x,y,x2,y2, i, j, d; const int dia_size= c->dia_size&0xFE; static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2}, @@ -765,7 +763,7 @@ static int full_search(MpegEncContext * s, int *best, int dmin, me_cmp_func cmpf, chroma_cmpf; LOAD_COMMON LOAD_COMMON2 - int map_generation= c->map_generation; + unsigned map_generation = c->map_generation; int x,y, d; const int dia_size= c->dia_size&0xFF; @@ -794,7 +792,7 @@ static int full_search(MpegEncContext * s, int *best, int dmin, #define SAB_CHECK_MV(ax,ay)\ {\ - const int key= ((ay)<map_generation; + unsigned map_generation = c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; @@ -918,7 +916,7 @@ static int var_diamond_search(MpegEncContext * s, int *best, int dmin, int dia_size; LOAD_COMMON LOAD_COMMON2 - int map_generation= c->map_generation; + unsigned map_generation = c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; @@ -992,8 +990,8 @@ static av_always_inline int diamond_search(MpegEncContext * s, int *best, int dm return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); } -/*! - \param P[10][2] a list of candidate mvs to check before starting the +/** + @param P a list of candidate mvs to check before starting the iterative search. If one of the candidates is close to the optimal mv, then it takes fewer iterations. And it increases the chance that we find the optimal mv. @@ -1010,7 +1008,7 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int int d; ///< the score (cmp + penalty) of any given mv int dmin; /*!< the best value of d, i.e. the score corresponding to the mv stored in best[]. */ - int map_generation; + unsigned map_generation; int penalty_factor; const int ref_mv_stride= s->mb_stride; //pass as arg FIXME const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME @@ -1138,7 +1136,7 @@ static int epzs_motion_search4(MpegEncContext * s, MotionEstContext * const c= &s->me; int best[2]={0, 0}; int d, dmin; - int map_generation; + unsigned map_generation; const int penalty_factor= c->penalty_factor; const int size=1; const int h=8; @@ -1198,7 +1196,7 @@ static int epzs_motion_search2(MpegEncContext * s, MotionEstContext * const c= &s->me; int best[2]={0, 0}; int d, dmin; - int map_generation; + unsigned map_generation; const int penalty_factor= c->penalty_factor; const int size=0; //FIXME pass as arg const int h=8; diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index 01558ab95b..1806e4703d 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -52,14 +52,21 @@ typedef struct MotionPixelsContext { static av_cold int mp_decode_init(AVCodecContext *avctx) { MotionPixelsContext *mp = avctx->priv_data; + int w4 = (avctx->width + 3) & ~3; + int h4 = (avctx->height + 3) & ~3; + + if(avctx->extradata_size < 2){ + av_log(avctx, AV_LOG_ERROR, "extradata too small\n"); + return AVERROR_INVALIDDATA; + } motionpixels_tableinit(); mp->avctx = avctx; dsputil_init(&mp->dsp, avctx); - mp->changes_map = av_mallocz(avctx->width * avctx->height); + mp->changes_map = av_mallocz(avctx->width * h4); mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1; mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel)); - mp->hpt = av_mallocz(avctx->height * avctx->width / 16 * sizeof(YuvPixel)); + mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel)); avctx->pix_fmt = PIX_FMT_RGB555; avcodec_get_frame_defaults(&mp->frame); return 0; @@ -189,10 +196,13 @@ static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) p = mp_get_yuv_from_rgb(mp, x - 1, y); } else { p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y = av_clip(p.y, 0, 31); if ((x & 3) == 0) { if ((y & 3) == 0) { p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v = av_clip(p.v, -32, 31); p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u = av_clip(p.u, -32, 31); mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p; } else { p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v; @@ -216,9 +226,12 @@ static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) p = mp_get_yuv_from_rgb(mp, 0, y); } else { p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y = av_clip(p.y, 0, 31); if ((y & 3) == 0) { p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v = av_clip(p.v, -32, 31); p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u = av_clip(p.u, -32, 31); } mp->vpt[y] = p; mp_set_rgb_from_yuv(mp, 0, y, &p); @@ -253,6 +266,7 @@ static int mp_decode_frame(AVCodecContext *avctx, mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); + memset(mp->bswapbuf + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&gb, mp->bswapbuf, buf_size * 8); memset(mp->changes_map, 0, avctx->width * avctx->height); @@ -279,7 +293,10 @@ static int mp_decode_frame(AVCodecContext *avctx, if (sz == 0) goto end; - init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0); + if (mp->max_codes_bits <= 0) + goto end; + if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0)) + goto end; mp_decode_frame_helper(mp, &gb); free_vlc(&mp->vlc); diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index bb21469356..6477edcf28 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -197,12 +197,19 @@ static int mpc7_decode_frame(AVCodecContext * avctx, int i, ch; int mb = -1; Band *bands = c->bands; - int off; + int off, out_size; int bits_used, bits_avail; memset(bands, 0, sizeof(bands)); if(buf_size <= 4){ av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size); + return AVERROR(EINVAL); + } + + out_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4; + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); } bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE); @@ -277,7 +284,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, *data_size = 0; return buf_size; } - *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4; + *data_size = out_size; return buf_size; } diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index 2864b1a010..4adc28ed25 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -127,6 +127,8 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) skip_bits(&gb, 3);//sample rate c->maxbands = get_bits(&gb, 5) + 1; + if (c->maxbands >= BANDS) + return AVERROR_INVALIDDATA; channels = get_bits(&gb, 4) + 1; if (channels > 2) { av_log_missing_feature(avctx, "Multichannel MPC SV8", 1); @@ -136,7 +138,8 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) c->frames = 1 << (get_bits(&gb, 3) * 2); avctx->sample_fmt = AV_SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + avctx->channel_layout = (channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + avctx->channels = channels; if(vlc_initialized) return 0; av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); @@ -241,10 +244,16 @@ static int mpc8_decode_frame(AVCodecContext * avctx, GetBitContext gb2, *gb = &gb2; int i, j, k, ch, cnt, res, t; Band *bands = c->bands; - int off; + int off, out_size; int maxband, keyframe; int last[2]; + out_size = MPC_FRAME_SIZE * 2 * avctx->channels; + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + keyframe = c->cur_frame == 0; if(keyframe){ @@ -260,6 +269,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2); if(maxband > 32) maxband -= 33; } + if(maxband > c->maxbands) + return AVERROR_INVALIDDATA; c->last_max_band = maxband; /* read subband indexes */ @@ -400,7 +411,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, c->last_bits_used = get_bits_count(gb); if(c->cur_frame >= c->frames) c->cur_frame = 0; - *data_size = MPC_FRAME_SIZE * 2 * avctx->channels; + *data_size = out_size; return c->cur_frame ? c->last_bits_used >> 3 : buf_size; } diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index bd858a59b7..ab6baa9bb6 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1151,6 +1151,7 @@ typedef struct Mpeg1Context { int save_width, save_height, save_progressive_seq; AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame? + int extradata_decoded; } Mpeg1Context; static av_cold int mpeg_decode_init(AVCodecContext *avctx) @@ -1287,7 +1288,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) { @@ -2315,8 +2316,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx, s->slice_count= 0; - if(avctx->extradata && !avctx->frame_number) + if (avctx->extradata && !s->extradata_decoded) { decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size); + s->extradata_decoded = 1; + } return decode_chunks(avctx, picture, data_size, buf, buf_size); } @@ -2475,10 +2478,18 @@ static int decode_chunks(AVCodecContext *avctx, /* Skip P-frames if we do not have a reference frame or we have an invalid header. */ if(s2->pict_type==AV_PICTURE_TYPE_P && !s->sync) break; } +#if FF_API_HURRY_UP + /* Skip B-frames if we are in a hurry. */ + if(avctx->hurry_up && s2->pict_type==FF_B_TYPE) break; +#endif if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==AV_PICTURE_TYPE_B) ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) break; +#if FF_API_HURRY_UP + /* Skip everything if we are in a hurry>=5. */ + if(avctx->hurry_up>=5) break; +#endif if (!s->mpeg_enc_ctx_allocated) break; diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 41344562b2..3c8229575a 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "dsputil.h" +#include "mathops.h" #include "mpegvideo.h" #include "mpeg12.h" @@ -681,8 +682,7 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) int bit_size = f_or_b_code - 1; int range = 1 << bit_size; /* modulo encoding */ - int l= INT_BIT - 5 - bit_size; - val= (val<>l; + val = sign_extend(val, 5 + bit_size); if (val >= 0) { val--; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 6b7b4bfbc0..06802cd2bb 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -651,13 +651,13 @@ try_again: if ((cbpc & 16) == 0) { /* 16x16 motion prediction */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if(!s->mcsel){ - mx = h263_decode_motion(s, pred_x, s->f_code); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; @@ -675,12 +675,12 @@ try_again: int i; s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { - int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y); - mx = h263_decode_motion(s, pred_x, s->f_code); + int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; mot_val[0] = mx; @@ -1245,14 +1245,14 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->field_select[0][0]= get_bits1(&s->gb); s->field_select[0][1]= get_bits1(&s->gb); - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); for(i=0; i<2; i++){ - mx = h263_decode_motion(s, pred_x, s->f_code); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y/2, s->f_code); + my = ff_h263_decode_motion(s, pred_y/2, s->f_code); if (my >= 0xffff) return -1; @@ -1263,13 +1263,13 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - mx = h263_decode_motion(s, pred_x, s->f_code); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; @@ -1280,12 +1280,12 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); - mx = h263_decode_motion(s, pred_x, s->f_code); + mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; s->mv[0][i][0] = mx; @@ -1381,8 +1381,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, if(USES_LIST(mb_type, 0)){ s->mv_dir = MV_DIR_FORWARD; - mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); - my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); + mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); + my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx; s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my; } @@ -1390,8 +1390,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, if(USES_LIST(mb_type, 1)){ s->mv_dir |= MV_DIR_BACKWARD; - mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); - my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); + mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); + my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx; s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my; } @@ -1402,8 +1402,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; for(i=0; i<2; i++){ - mx = h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); - my = h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); + mx = ff_h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); + my = ff_h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); s->last_mv[0][i][0]= s->mv[0][i][0] = mx; s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2; } @@ -1413,8 +1413,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir |= MV_DIR_BACKWARD; for(i=0; i<2; i++){ - mx = h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); - my = h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); + mx = ff_h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); + my = ff_h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); s->last_mv[1][i][0]= s->mv[1][i][0] = mx; s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2; } @@ -1426,8 +1426,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, if(IS_SKIP(mb_type)) mx=my=0; else{ - mx = h263_decode_motion(s, 0, 1); - my = h263_decode_motion(s, 0, 1); + mx = ff_h263_decode_motion(s, 0, 1); + my = ff_h263_decode_motion(s, 0, 1); } s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index bdff535a99..70c6c53011 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -727,7 +727,7 @@ void mpeg4_encode_mb(MpegEncContext * s, } /* motion vectors: 16x16 mode */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_h263_encode_motion_vector(s, motion_x - pred_x, motion_y - pred_y, s->f_code); @@ -751,7 +751,7 @@ void mpeg4_encode_mb(MpegEncContext * s, } /* motion vectors: 16x8 interlaced mode */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); pred_y /=2; put_bits(&s->pb, 1, s->field_select[0][0]); @@ -779,7 +779,7 @@ void mpeg4_encode_mb(MpegEncContext * s, for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ - h263_pred_motion(s, i, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); @@ -898,8 +898,8 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ s->last_time_base= FFUDIV(time, s->avctx->time_base.den); seconds= FFUDIV(time, s->avctx->time_base.den); - minutes= FFUDIV(seconds, 60); FFUMOD(seconds, 60); - hours = FFUDIV(minutes, 60); FFUMOD(minutes, 60); + minutes= FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60); + hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60); hours = FFUMOD(hours , 24); put_bits(&s->pb, 5, hours); diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 56a48ce71b..e5b60e2fb1 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -210,7 +210,7 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){ else g->long_end = 4; /* 8000 Hz */ - g->short_start = 2 + (s->sample_rate_index != 8); + g->short_start = 3; } else { g->long_end = 0; g->short_start = 0; @@ -1801,15 +1801,15 @@ static int decode_frame(AVCodecContext * avctx, avctx->bit_rate = s->bit_rate; avctx->sub_id = s->layer; - if(*data_size < 1152*avctx->channels*sizeof(OUT_INT)) - return -1; + if (*data_size < avctx->frame_size * avctx->channels * sizeof(OUT_INT)) + return AVERROR(EINVAL); *data_size = 0; if(s->frame_size<=0 || s->frame_size > buf_size){ av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); return -1; }else if(s->frame_size < buf_size){ - av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n"); + av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n"); buf_size= s->frame_size; } @@ -1870,6 +1870,9 @@ static int decode_frame_adu(AVCodecContext * avctx, avctx->bit_rate = s->bit_rate; avctx->sub_id = s->layer; + if (*data_size < avctx->frame_size * avctx->channels * sizeof(OUT_INT)) + return AVERROR(EINVAL); + s->frame_size = len; if (avctx->parse_only) { diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index c3c3e15033..51d57dbe74 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -285,9 +285,10 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared){ } FF_ALLOCZ_OR_GOTO(s->avctx, pic->mbskip_table , mb_array_size * sizeof(uint8_t)+2, fail) //the +2 is for the slice end check - FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table , mb_array_size * sizeof(uint8_t) , fail) + FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table_base , (big_mb_num + s->mb_stride) * sizeof(uint8_t) , fail) FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base , (big_mb_num + s->mb_stride) * sizeof(uint32_t), fail) pic->mb_type= pic->mb_type_base + 2*s->mb_stride+1; + pic->qscale_table = pic->qscale_table_base + 2*s->mb_stride + 1; if(s->out_format == FMT_H264){ for(i=0; i<2; i++){ FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], 2 * (b4_array_size+4) * sizeof(int16_t), fail) @@ -339,7 +340,7 @@ static void free_picture(MpegEncContext *s, Picture *pic){ av_freep(&pic->mc_mb_var); av_freep(&pic->mb_mean); av_freep(&pic->mbskip_table); - av_freep(&pic->qscale_table); + av_freep(&pic->qscale_table_base); av_freep(&pic->mb_type_base); av_freep(&pic->dct_coeff); av_freep(&pic->pan_scan); @@ -365,8 +366,8 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){ int i; // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264) - FF_ALLOCZ_OR_GOTO(s->avctx, s->allocated_edge_emu_buffer, (s->width+64)*2*21*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance - s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21; + FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer, (s->width+64)*2*21*2*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance + //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer() FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, (s->width+64)*4*16*2*sizeof(uint8_t), fail) @@ -404,7 +405,7 @@ fail: static void free_duplicate_context(MpegEncContext *s){ if(s==NULL) return; - av_freep(&s->allocated_edge_emu_buffer); s->edge_emu_buffer= NULL; + av_freep(&s->edge_emu_buffer); av_freep(&s->me.scratchpad); s->me.temp= s->rd_scratchpad= @@ -421,7 +422,6 @@ static void free_duplicate_context(MpegEncContext *s){ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src){ #define COPY(a) bak->a= src->a - COPY(allocated_edge_emu_buffer); COPY(edge_emu_buffer); COPY(me.scratchpad); COPY(me.temp); @@ -1138,6 +1138,9 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) } } +#if FF_API_HURRY_UP + s->hurry_up= s->avctx->hurry_up; +#endif s->error_recognition= avctx->error_recognition; /* set dequantizer, we can't do it during init as it might change for mpeg4 @@ -2147,6 +2150,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], } /* skip dequant / idct if we are really late ;) */ +#if FF_API_HURRY_UP + if(s->hurry_up>1) goto skip_idct; +#endif if(s->avctx->skip_idct){ if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) @@ -2301,12 +2307,15 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ edge_h= FFMIN(h, s->v_edge_pos - y); - s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize , s->linesize, - s->h_edge_pos , edge_h , EDGE_WIDTH , EDGE_WIDTH , sides); - s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>vshift)*s->uvlinesize, s->uvlinesize, - s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides); - s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>vshift)*s->uvlinesize, s->uvlinesize, - s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides); + s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize, + s->linesize, s->h_edge_pos, edge_h, + EDGE_WIDTH, EDGE_WIDTH, sides); + s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>vshift)*s->uvlinesize, + s->uvlinesize, s->h_edge_pos>>hshift, edge_h>>vshift, + EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides); + s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>vshift)*s->uvlinesize, + s->uvlinesize, s->h_edge_pos>>hshift, edge_h>>vshift, + EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides); } h= FFMIN(h, s->avctx->height - y); diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index a0ff354a08..21eeafa596 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -88,6 +88,7 @@ typedef struct Picture{ * halfpel luma planes. */ uint8_t *interpolated[3]; + int8_t *qscale_table_base; int16_t (*motion_val_base[2])[2]; uint32_t *mb_type_base; #define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type @@ -122,7 +123,7 @@ typedef struct Picture{ int pic_id; /**< h264 pic_num (short -> no wrap version of pic_num, pic_num & max_pic_num; long -> long_pic_num) */ int long_ref; ///< 1->long term reference 0->short term reference - int ref_poc[2][2][16]; ///< h264 POCs of the frames used as reference (FIXME need per slice) + int ref_poc[2][2][32]; ///< h264 POCs of the frames/fields used as reference (FIXME need per slice) int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF int field_picture; ///< whether or not the picture was encoded in seperate fields @@ -152,7 +153,7 @@ typedef struct MotionEstContext{ int best_bits; uint32_t *map; ///< map to avoid duplicate evaluations uint32_t *score_map; ///< map to store the scores - int map_generation; + unsigned map_generation; int pre_penalty_factor; int penalty_factor; /*!< an estimate of the bits required to code a given mv value, e.g. (1,0) takes @@ -316,8 +317,7 @@ typedef struct MpegEncContext { uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding - uint8_t *allocated_edge_emu_buffer; - uint8_t *edge_emu_buffer; ///< points into the middle of allocated_edge_emu_buffer + uint8_t *edge_emu_buffer; ///< temporary buffer for if MVs point to out-of-frame data uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision uint8_t *obmc_scratchpad; uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers @@ -391,6 +391,11 @@ typedef struct MpegEncContext { int no_rounding; /**< apply no rounding to motion compensation (MPEG4, msmpeg4, ...) for b-frames rounding mode is always 0 */ +#if FF_API_HURRY_UP + int hurry_up; /**< when set to 1 during decoding, b frames will be skipped + when set to 2 idct/dequant will be skipped too */ +#endif + /* macroblock layer */ int mb_x, mb_y; int mb_skip_run; diff --git a/libavcodec/mpegvideo_common.h b/libavcodec/mpegvideo_common.h index 18e49a63c3..f7ff57a3ef 100644 --- a/libavcodec/mpegvideo_common.h +++ b/libavcodec/mpegvideo_common.h @@ -725,7 +725,8 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, 0, 0, 0, ref_picture, pix_op, qpix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else if(!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel){ + } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && + s->mspel && s->codec_id == CODEC_ID_WMV2) { ff_mspel_motion(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index a6e9c7c7be..7d03a8f61b 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -411,9 +411,10 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if ((s->codec_id == CODEC_ID_MPEG4 || s->codec_id == CODEC_ID_H263 || s->codec_id == CODEC_ID_H263P) && (avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den > 255)) { - av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i, limit is 255/255\n", + av_log(avctx, AV_LOG_WARNING, "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n", avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); - return -1; + av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den, + avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 255); } if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)) @@ -581,7 +582,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) break; case CODEC_ID_H263: if (!CONFIG_H263_ENCODER) return -1; - if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height) == 8) { + if (ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format), s->width, s->height) == 8) { av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height); return -1; } @@ -707,7 +708,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if (CONFIG_H261_ENCODER && s->out_format == FMT_H261) ff_h261_encode_init(s); if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) - h263_encode_init(s); + ff_h263_encode_init(s); if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version) ff_msmpeg4_encode_init(s); if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) @@ -972,7 +973,7 @@ static int estimate_best_b_count(MpegEncContext *s){ c->time_base= s->avctx->time_base; c->max_b_frames= s->max_b_frames; - if (avcodec_open(c, codec) < 0) + if (avcodec_open2(c, codec, NULL) < 0) return -1; for(i=0; imax_b_frames+2; i++){ @@ -1767,7 +1768,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, case CODEC_ID_RV10: case CODEC_ID_RV20: if (CONFIG_H263_ENCODER) - h263_encode_mb(s, s->block, motion_x, motion_y); + ff_h263_encode_mb(s, s->block, motion_x, motion_y); break; case CODEC_ID_MJPEG: if (CONFIG_MJPEG_ENCODER) @@ -2006,7 +2007,7 @@ static int mb_var_thread(AVCodecContext *c, void *arg){ int varc; int sum = s->dsp.pix_sum(pix, s->linesize); - varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; + varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)sum*sum)>>8) + 500 + 128)>>8; s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc; s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; @@ -2199,7 +2200,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ case CODEC_ID_H263: case CODEC_ID_H263P: if (CONFIG_H263_ENCODER) - h263_encode_gob_header(s, mb_y); + ff_h263_encode_gob_header(s, mb_y); break; } @@ -2949,7 +2950,7 @@ static int encode_picture(MpegEncContext *s, int picture_number) else if (CONFIG_FLV_ENCODER && s->codec_id == CODEC_ID_FLV1) ff_flv_encode_picture_header(s, picture_number); else if (CONFIG_H263_ENCODER) - h263_encode_picture_header(s, picture_number); + ff_h263_encode_picture_header(s, picture_number); break; case FMT_MPEG1: if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index 06098b04a1..5759e8f850 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -511,7 +511,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) if (val == 0) { /* zero vector */ code = 0; - put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); + put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); } else { bit_size = s->f_code - 1; range = 1 << bit_size; @@ -530,7 +530,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) code = (val >> bit_size) + 1; bits = val & (range - 1); - put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); + put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); } @@ -579,7 +579,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, s->misc_bits += get_bits_diff(s); - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); msmpeg4v2_encode_motion(s, motion_x - pred_x); msmpeg4v2_encode_motion(s, motion_y - pred_y); }else{ @@ -590,7 +590,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, s->misc_bits += get_bits_diff(s); /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); } @@ -1138,7 +1138,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) cbp|= cbpy<<2; if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; - h263_pred_motion(s, 0, 0, &mx, &my); + ff_h263_pred_motion(s, 0, 0, &mx, &my); mx= msmpeg4v2_decode_motion(s, mx, 1); my= msmpeg4v2_decode_motion(s, my, 1); @@ -1224,7 +1224,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->rl_table_index = decode012(&s->gb); s->rl_chroma_table_index = s->rl_table_index; } - h263_pred_motion(s, 0, 0, &mx, &my); + ff_h263_pred_motion(s, 0, 0, &mx, &my); if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0) return -1; s->mv_dir = MV_DIR_FORWARD; @@ -1320,8 +1320,8 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) &v2_mb_type[0][1], 2, 1, &v2_mb_type[0][0], 2, 1, 128); INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 538); + &ff_mvtab[0][1], 2, 1, + &ff_mvtab[0][0], 2, 1, 538); INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128, &wmv2_inter_table[0][0][1], 8, 4, diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c index f72715dea0..9a7e1b7f05 100644 --- a/libavcodec/msmpeg4data.c +++ b/libavcodec/msmpeg4data.c @@ -592,9 +592,9 @@ static const int8_t table4_run[168] = { 29, 30, 31, 32, 33, 34, 35, 36, }; -extern const uint16_t inter_vlc[103][2]; -extern const int8_t inter_level[102]; -extern const int8_t inter_run[102]; +extern const uint16_t ff_inter_vlc[103][2]; +extern const int8_t ff_inter_level[102]; +extern const int8_t ff_inter_run[102]; extern const uint16_t ff_mpeg4_intra_vlc[103][2]; extern const int8_t ff_mpeg4_intra_level[102]; @@ -647,9 +647,9 @@ RLTable rl_table[NB_RL_TABLES] = { { 102, 58, - inter_vlc, - inter_run, - inter_level, + ff_inter_vlc, + ff_inter_run, + ff_inter_level, }, }; diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c index 496eb40916..cd81200c37 100644 --- a/libavcodec/msrle.c +++ b/libavcodec/msrle.c @@ -26,6 +26,9 @@ * http://www.pcisys.net/~melanson/codecs/ * * The MS RLE decoder outputs PAL8 colorspace data. + * + * Note that this decoder expects the palette colors from the end of the + * BITMAPINFO header passed through palctrl. */ #include @@ -43,7 +46,6 @@ typedef struct MsrleContext { const unsigned char *buf; int size; - uint32_t pal[256]; } MsrleContext; static av_cold int msrle_decode_init(AVCodecContext *avctx) @@ -93,16 +95,13 @@ static int msrle_decode_frame(AVCodecContext *avctx, return -1; } - if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - - if (pal) { - s->frame.palette_has_changed = 1; - memcpy(s->pal, pal, AVPALETTE_SIZE); - } - + if (s->avctx->palctrl) { /* make the palette available */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); + if (s->avctx->palctrl->palette_changed) { + s->frame.palette_has_changed = 1; + s->avctx->palctrl->palette_changed = 0; + } } /* FIXME how to correctly detect RLE ??? */ diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c index c1c7d48080..bd55cad3b9 100644 --- a/libavcodec/msvideo1.c +++ b/libavcodec/msvideo1.c @@ -25,6 +25,9 @@ * For more information about the MS Video-1 format, visit: * http://www.pcisys.net/~melanson/codecs/ * + * This decoder outputs either PAL8 or RGB555 data, depending on the + * whether a RGB palette was passed through palctrl; + * if it's present, then the data is PAL8; RGB555 otherwise. */ #include @@ -52,7 +55,6 @@ typedef struct Msvideo1Context { int mode_8bit; /* if it's not 8-bit, it's 16-bit */ - uint32_t pal[256]; } Msvideo1Context; static av_cold int msvideo1_decode_init(AVCodecContext *avctx) @@ -62,7 +64,7 @@ static av_cold int msvideo1_decode_init(AVCodecContext *avctx) s->avctx = avctx; /* figure out the colorspace based on the presence of a palette */ - if (s->avctx->bits_per_coded_sample == 8) { + if (s->avctx->palctrl) { s->mode_8bit = 1; avctx->pix_fmt = PIX_FMT_PAL8; } else { @@ -172,8 +174,13 @@ static void msvideo1_decode_8bit(Msvideo1Context *s) } /* make the palette available on the way out */ - if (s->avctx->pix_fmt == PIX_FMT_PAL8) - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + if (s->avctx->pix_fmt == PIX_FMT_PAL8) { + memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); + if (s->avctx->palctrl->palette_changed) { + s->frame.palette_has_changed = 1; + s->avctx->palctrl->palette_changed = 0; + } + } } static void msvideo1_decode_16bit(Msvideo1Context *s) @@ -303,15 +310,6 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, return -1; } - if (s->mode_8bit) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - - if (pal) { - memcpy(s->pal, pal, AVPALETTE_SIZE); - s->frame.palette_has_changed = 1; - } - } - if (s->mode_8bit) msvideo1_decode_8bit(s); else diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 59c1b3bdd8..387a6cf465 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -156,19 +156,27 @@ static int decode_tag(AVCodecContext * avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; NellyMoserDecodeContext *s = avctx->priv_data; - int blocks, i; + int data_max = *data_size; + int blocks, i, block_size; int16_t* samples; - *data_size = 0; samples = (int16_t*)data; - if (buf_size < avctx->block_align) + if (buf_size < avctx->block_align) { + *data_size = 0; return buf_size; + } if (buf_size % 64) { av_log(avctx, AV_LOG_ERROR, "Tag size %d.\n", buf_size); + *data_size = 0; return buf_size; } - blocks = buf_size / 64; + block_size = NELLY_SAMPLES * av_get_bytes_per_sample(avctx->sample_fmt); + blocks = FFMIN(buf_size / 64, *data_size / block_size); + if (blocks <= 0) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } /* Normal numbers of blocks for sample rates: * 8000 Hz - 1 * 11025 Hz - 2 @@ -178,10 +186,12 @@ static int decode_tag(AVCodecContext * avctx, */ for (i=0 ; i data_max) + return i > 0 ? i * NELLY_BLOCK_LEN : -1; nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf); s->fmt_conv.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES); - *data_size += NELLY_SAMPLES*sizeof(int16_t); } + *data_size = blocks * block_size; return buf_size; } diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 1d35cda9a1..f32b5b2f10 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -287,7 +287,7 @@ static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int apply_mdct(s); - init_put_bits(&pb, output, output_size * 8); + init_put_bits(&pb, output, output_size); i = 0; for (band = 0; band < NELLY_BANDS; band++) { diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 6eb6de3101..bb20b93b95 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -20,6 +20,7 @@ */ #include #include +#include #include "libavutil/bswap.h" #include "libavutil/lzo.h" @@ -112,19 +113,23 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height, int qualit if (quality >= 0) get_quant_quality(c, quality); if (width != c->width || height != c->height) { - if (av_image_check_size(height, width, 0, avctx) < 0) - return 0; + // 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) + return -1; avctx->width = c->width = width; avctx->height = c->height = height; - av_fast_malloc(&c->decomp_buf, &c->decomp_size, c->height * c->width * 3 / 2); + av_fast_malloc(&c->decomp_buf, &c->decomp_size, buf_size); if (!c->decomp_buf) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 0; + return AVERROR(ENOMEM); } rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); + return 1; } else if (quality != c->quality) rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); - return 1; + return 0; } static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, @@ -135,6 +140,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVFrame *picture = data; int orig_size = buf_size; int keyframe; + int size_change = 0; int result; enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3', @@ -172,32 +178,41 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, default: keyframe = 1; break; } +retry: // skip rest of the frameheader. buf = &buf[12]; buf_size -= 12; if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { - int outlen = c->decomp_size, inlen = buf_size; + int outlen = c->decomp_size - AV_LZO_OUTPUT_PADDING, inlen = buf_size; if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); buf = c->decomp_buf; - buf_size = c->decomp_size; + buf_size = c->decomp_size - AV_LZO_OUTPUT_PADDING; } if (c->codec_frameheader) { - int w, h, q; - if (buf_size < 12) { + int w, h, q, res; + if (buf_size < RTJPEG_HEADER_SIZE || buf[4] != RTJPEG_HEADER_SIZE || + buf[5] != RTJPEG_FILE_VERSION) { av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); - return -1; + return AVERROR_INVALIDDATA; } w = AV_RL16(&buf[6]); h = AV_RL16(&buf[8]); q = buf[10]; - if (!codec_reinit(avctx, w, h, q)) - return -1; - buf = &buf[12]; - buf_size -= 12; + res = codec_reinit(avctx, w, h, q); + if (res < 0) + return res; + if (res) { + buf = avpkt->data; + buf_size = avpkt->size; + size_change = 1; + goto retry; + } + buf = &buf[RTJPEG_HEADER_SIZE]; + buf_size -= RTJPEG_HEADER_SIZE; } - if (keyframe && c->pic.data[0]) + if ((size_change || keyframe) && c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); c->pic.reference = 3; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | @@ -259,7 +274,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { if (avctx->extradata_size) get_quant(avctx, c, avctx->extradata, avctx->extradata_size); dsputil_init(&c->dsp, avctx); - if (!codec_reinit(avctx, avctx->width, avctx->height, -1)) + if (codec_reinit(avctx, avctx->width, avctx->height, -1) < 0) return 1; return 0; } diff --git a/libavcodec/opt.c b/libavcodec/opt.c new file mode 100644 index 0000000000..f41fae0ba1 --- /dev/null +++ b/libavcodec/opt.c @@ -0,0 +1,89 @@ +/* + * AVOptions ABI compatibility wrapper + * Copyright (c) 2010 Michael Niedermayer + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "opt.h" + +#if LIBAVCODEC_VERSION_MAJOR < 53 && CONFIG_SHARED && HAVE_SYMVER + +FF_SYMVER(const AVOption *, av_find_opt, (void *obj, const char *name, const char *unit, int mask, int flags), "LIBAVCODEC_52"){ + return av_find_opt(obj, name, unit, mask, flags); +} +FF_SYMVER(int, av_set_string3, (void *obj, const char *name, const char *val, int alloc, const AVOption **o_out), "LIBAVCODEC_52"){ + return av_set_string3(obj, name, val, alloc, o_out); +} +FF_SYMVER(const AVOption *, av_set_double, (void *obj, const char *name, double n), "LIBAVCODEC_52"){ + return av_set_double(obj, name, n); +} +FF_SYMVER(const AVOption *, av_set_q, (void *obj, const char *name, AVRational n), "LIBAVCODEC_52"){ + return av_set_q(obj, name, n); +} +FF_SYMVER(const AVOption *, av_set_int, (void *obj, const char *name, int64_t n), "LIBAVCODEC_52"){ + return av_set_int(obj, name, n); +} +FF_SYMVER(double, av_get_double, (void *obj, const char *name, const AVOption **o_out), "LIBAVCODEC_52"){ + return av_get_double(obj, name, o_out); +} +FF_SYMVER(AVRational, av_get_q, (void *obj, const char *name, const AVOption **o_out), "LIBAVCODEC_52"){ + return av_get_q(obj, name, o_out); +} +FF_SYMVER(int64_t, av_get_int, (void *obj, const char *name, const AVOption **o_out), "LIBAVCODEC_52"){ + return av_get_int(obj, name, o_out); +} +FF_SYMVER(const char *, av_get_string, (void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len), "LIBAVCODEC_52"){ + return av_get_string(obj, name, o_out, buf, buf_len); +} +FF_SYMVER(const AVOption *, av_next_option, (void *obj, const AVOption *last), "LIBAVCODEC_52"){ + return av_next_option(obj, last); +} +FF_SYMVER(int, av_opt_show2, (void *obj, void *av_log_obj, int req_flags, int rej_flags), "LIBAVCODEC_52"){ + return av_opt_show2(obj, av_log_obj, req_flags, rej_flags); +} +FF_SYMVER(void, av_opt_set_defaults, (void *s), "LIBAVCODEC_52"){ + return av_opt_set_defaults(s); +} +FF_SYMVER(void, av_opt_set_defaults2, (void *s, int mask, int flags), "LIBAVCODEC_52"){ + return av_opt_set_defaults2(s, mask, flags); +} +#endif + +#if FF_API_SET_STRING_OLD +const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){ + const AVOption *o; + if (av_set_string3(obj, name, val, alloc, &o) < 0) + return NULL; + return o; +} + +const AVOption *av_set_string(void *obj, const char *name, const char *val){ + const AVOption *o; + if (av_set_string3(obj, name, val, 0, &o) < 0) + return NULL; + return o; +} +#endif + +#if FF_API_OPT_SHOW +int av_opt_show(void *obj, void *av_log_obj){ + return av_opt_show2(obj, av_log_obj, + AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0); +} +#endif diff --git a/libavcodec/opt.h b/libavcodec/opt.h index 70de27d192..505377d7d9 100644 --- a/libavcodec/opt.h +++ b/libavcodec/opt.h @@ -1,3 +1,24 @@ +/* + * AVOptions + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + /** * @file * This header is provided for compatibility only and will be removed @@ -7,10 +28,34 @@ #ifndef AVCODEC_OPT_H #define AVCODEC_OPT_H -#include "libavcodec/version.h" +/** + * @file + * AVOptions + */ -#if FF_API_OPT_H +#include "libavutil/rational.h" +#include "avcodec.h" #include "libavutil/opt.h" + +#if FF_API_SET_STRING_OLD +/** + * @see av_set_string2() + */ +attribute_deprecated const AVOption *av_set_string(void *obj, const char *name, const char *val); + +/** + * @return a pointer to the AVOption corresponding to the field set or + * NULL if no matching AVOption exists, or if the value val is not + * valid + * @see av_set_string3() + */ +attribute_deprecated const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc); +#endif +#if FF_API_OPT_SHOW +/** + * @deprecated Use av_opt_show2() instead. + */ +attribute_deprecated int av_opt_show(void *obj, void *av_log_obj); #endif #endif /* AVCODEC_OPT_H */ diff --git a/libavcodec/options.c b/libavcodec/options.c index b6ad5d8763..0a0a442f87 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -438,6 +438,7 @@ static const AVOption options[]={ {"crf_max", "in crf mode, prevents vbv from lowering quality beyond this point", OFFSET(crf_max), FF_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 51, V|E}, {"log_level_offset", "set the log level offset", OFFSET(log_level_offset), FF_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX }, #if FF_API_FLAC_GLOBAL_OPTS +{"use_lpc", "sets whether to use LPC mode (FLAC)", OFFSET(use_lpc), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E}, {"lpc_type", "deprecated, use flac-specific options", OFFSET(lpc_type), FF_OPT_TYPE_INT, {.dbl = AV_LPC_TYPE_DEFAULT }, AV_LPC_TYPE_DEFAULT, AV_LPC_TYPE_NB-1, A|E}, {"none", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_NONE }, INT_MIN, INT_MAX, A|E, "lpc_type"}, {"fixed", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_FIXED }, INT_MIN, INT_MAX, A|E, "lpc_type"}, @@ -446,10 +447,9 @@ static const AVOption options[]={ {"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E}, #endif {"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E}, -{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_INT, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"}, +{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"}, {"slice", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"frame", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, -{"vbv_delay", "initial buffer fill time in periods of 27Mhz clock", 0, FF_OPT_TYPE_INT64, {.dbl = 0 }, 0, INT64_MAX}, {"audio_service_type", "audio service type", OFFSET(audio_service_type), FF_OPT_TYPE_INT, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, {"ma", "Main Audio Service", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"ef", "Effects", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, diff --git a/libavcodec/parser.c b/libavcodec/parser.c index d4a6126611..e4dc040603 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -105,6 +105,43 @@ void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove){ } } +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * + * @param buf input + * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output) + * @param pts input presentation timestamp + * @param dts input decoding timestamp + * @param poutbuf will contain a pointer to the first byte of the output frame + * @param poutbuf_size will contain the length of the output frame + * @return the number of bytes of the input bitstream used + * + * Example: + * @code + * while(in_len){ + * len = av_parser_parse(myparser, AVCodecContext, &data, &size, + * in_data, in_len, + * pts, dts); + * in_data += len; + * in_len -= len; + * + * if(size) + * decode_frame(data, size); + * } + * @endcode + * + * @deprecated Use av_parser_parse2() instead. + */ +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts) +{ + return av_parser_parse2(s, avctx, poutbuf, poutbuf_size, buf, buf_size, pts, dts, AV_NOPTS_VALUE); +} +#endif + int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, @@ -242,8 +279,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; @@ -256,11 +295,15 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s /* append to buffer */ if(pc->index){ void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - - if(!new_buffer) + if(!new_buffer) { + pc->overread_index = + pc->index = 0; return AVERROR(ENOMEM); + } pc->buffer = new_buffer; - memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); + if (next > -FF_INPUT_BUFFER_PADDING_SIZE) + memcpy(&pc->buffer[pc->index], *buf, + next + FF_INPUT_BUFFER_PADDING_SIZE); pc->index = 0; *buf= pc->buffer; } diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 05ba027802..a8c1d88449 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -107,7 +107,7 @@ static void png_put_interlaced_row(uint8_t *dst, int width, static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) { long i; - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for(i=0; i<=w-(int)sizeof(long); i+=sizeof(long)){ long a = *(long*)(src1+i); long b = *(long*)(src2+i); *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); @@ -148,7 +148,7 @@ static void add_paeth_prediction_c(uint8_t *dst, uint8_t *src, uint8_t *top, int 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]);\ @@ -164,13 +164,9 @@ static void add_paeth_prediction_c(uint8_t *dst, uint8_t *src, uint8_t *top, int 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(PNGDecContext *s, uint8_t *dst, int filter_type, @@ -422,6 +418,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 = bytestream_get_be32(&s->bytestream); s->height = bytestream_get_be32(&s->bytestream); if(av_image_check_size(s->width, s->height, 0, avctx)){ @@ -467,12 +469,14 @@ static int decode_frame(AVCodecContext *avctx, } else if (s->bit_depth == 16 && s->color_type == PNG_COLOR_TYPE_RGB) { avctx->pix_fmt = PIX_FMT_RGB48BE; - } else if (s->bit_depth == 1) { + } else if (s->bit_depth == 1 && s->bits_per_pixel == 1) { avctx->pix_fmt = PIX_FMT_MONOBLACK; - } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = PIX_FMT_PAL8; - } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - avctx->pix_fmt = PIX_FMT_GRAY8A; + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + avctx->pix_fmt = PIX_FMT_Y400A; } else { goto fail; } @@ -586,9 +590,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/pngenc.c b/libavcodec/pngenc.c index c4ef2fd945..5812cdad75 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -55,7 +55,7 @@ static void png_get_interlaced_row(uint8_t *dst, int row_size, uint8_t *d; const uint8_t *s; - mask = ff_png_pass_mask[pass]; + mask = (int[]){0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}[pass]; switch(bits_per_pixel) { case 1: memset(dst, 0, row_size); diff --git a/libavcodec/ppc/asm.S b/libavcodec/ppc/asm.S index 2706d6b1d8..bbbf8a4a66 100644 --- a/libavcodec/ppc/asm.S +++ b/libavcodec/ppc/asm.S @@ -44,10 +44,13 @@ X(\name): L(\name): .endm -.macro movrel rd, sym +.macro movrel rd, sym, gp ld \rd, \sym@got(r2) .endm +.macro get_got rd +.endm + #else /* ARCH_PPC64 */ #define PTR .int @@ -65,19 +68,25 @@ X(\name): \name: .endm -.macro movrel rd, sym +.macro movrel rd, sym, gp #if CONFIG_PIC - bcl 20, 31, lab_pic_\@ -lab_pic_\@: - mflr \rd - addis \rd, \rd, (\sym - lab_pic_\@)@ha - addi \rd, \rd, (\sym - lab_pic_\@)@l + lwz \rd, \sym@got(\gp) #else lis \rd, \sym@ha la \rd, \sym@l(\rd) #endif .endm +.macro get_got rd +#if CONFIG_PIC + bcl 20, 31, .Lgot\@ +.Lgot\@: + mflr \rd + addis \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@ha + addi \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@l +#endif +.endm + #endif /* ARCH_PPC64 */ #if HAVE_IBM_ASM diff --git a/libavcodec/ppc/fft_altivec_s.S b/libavcodec/ppc/fft_altivec_s.S index 5d3c5406c3..16ce838c97 100644 --- a/libavcodec/ppc/fft_altivec_s.S +++ b/libavcodec/ppc/fft_altivec_s.S @@ -353,6 +353,7 @@ extfunc ff_fft_calc\interleave\()_altivec mflr r0 stp r0, 2*PS(r1) stpu r1, -(160+16*PS)(r1) + get_got r11 addi r6, r1, 16*PS stvm r6, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 mfvrsave r0 @@ -360,14 +361,14 @@ extfunc ff_fft_calc\interleave\()_altivec li r6, 0xfffffffc mtvrsave r6 - movrel r6, fft_data + movrel r6, fft_data, r11 lvm r6, v14, v15, v16, v17, v18, v19, v20, v21 lvm r6, v22, v23, v24, v25, v26, v27, v28, v29 li r9, 16 - movrel r12, X(ff_cos_tabs) + movrel r12, X(ff_cos_tabs), r11 - movrel r6, fft_dispatch_tab\interleave\()_altivec + movrel r6, fft_dispatch_tab\interleave\()_altivec, r11 lwz r3, 0(r3) subi r3, r3, 2 slwi r3, r3, 2+ARCH_PPC64 diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index e662fb9caf..af0048ac5e 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -332,6 +332,9 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->height = src->height; dst->pix_fmt = src->pix_fmt; + dst->coded_width = src->coded_width; + dst->coded_height = src->coded_height; + dst->has_b_frames = src->has_b_frames; dst->idct_algo = src->idct_algo; dst->slice_count = src->slice_count; @@ -380,6 +383,9 @@ static void update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->release_buffer = src->release_buffer; dst->opaque = src->opaque; +#if FF_API_HURRY_UP + dst->hurry_up = src->hurry_up; +#endif dst->dsp_mask = src->dsp_mask; dst->debug = src->debug; dst->debug_mv = src->debug_mv; @@ -408,9 +414,10 @@ static void release_delayed_buffers(PerThreadContext *p) FrameThreadContext *fctx = p->parent; while (p->num_released_buffers > 0) { - AVFrame *f = &p->released_buffers[--p->num_released_buffers]; + AVFrame *f; pthread_mutex_lock(&fctx->buffer_mutex); + f = &p->released_buffers[--p->num_released_buffers]; free_progress(f); f->thread_opaque = NULL; @@ -746,9 +753,12 @@ void ff_thread_flush(AVCodecContext *avctx) if (!avctx->thread_opaque) return; park_frame_worker_threads(fctx, avctx->thread_count); - - if (fctx->prev_thread) - update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0); + if (fctx->prev_thread) { + if (fctx->prev_thread != &fctx->threads[0]) + update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0); + if (avctx->codec->flush) + avctx->codec->flush(fctx->threads[0].avctx); + } fctx->next_decoding = fctx->next_finished = 0; fctx->delaying = 1; @@ -836,6 +846,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) { PerThreadContext *p = avctx->thread_opaque; + FrameThreadContext *fctx; if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { avctx->release_buffer(avctx, f); @@ -851,7 +862,10 @@ void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p, %d buffers used\n", f, f->owner->internal_buffer_count); + fctx = p->parent; + pthread_mutex_lock(&fctx->buffer_mutex); p->released_buffers[p->num_released_buffers++] = *f; + pthread_mutex_unlock(&fctx->buffer_mutex); memset(f->data, 0, sizeof(f->data)); } diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c index 3273fd2f8e..14a4972a7a 100644 --- a/libavcodec/ptx.c +++ b/libavcodec/ptx.c @@ -39,12 +39,15 @@ static av_cold int ptx_init(AVCodecContext *avctx) { static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; PTXContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; unsigned int offset, w, h, y, stride, bytes_per_pixel; uint8_t *ptr; + if (buf_end - buf < 14) + return AVERROR_INVALIDDATA; offset = AV_RL16(buf); w = AV_RL16(buf+8); h = AV_RL16(buf+10); @@ -57,6 +60,8 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->pix_fmt = PIX_FMT_RGB555; + if (buf_end - buf < offset) + return AVERROR_INVALIDDATA; if (offset != 0x2c) av_log_ask_for_sample(avctx, "offset != 0x2c\n"); @@ -80,6 +85,8 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, stride = p->linesize[0]; for (y=0; ybit_buf<<= s->bit_left; + if (s->bit_left < 32) + s->bit_buf<<= s->bit_left; #endif while (s->bit_left < 32) { /* XXX: should test end of buffer */ diff --git a/libavcodec/qcelpdata.h b/libavcodec/qcelpdata.h index d79cea9f6c..df04435af2 100644 --- a/libavcodec/qcelpdata.h +++ b/libavcodec/qcelpdata.h @@ -38,14 +38,14 @@ * QCELP unpacked data frame */ typedef struct { -/// @defgroup qcelp_codebook_parameters QCELP excitation codebook parameters +/// @name QCELP excitation codebook parameters /// @{ uint8_t cbsign[16]; ///!< sign of the codebook gain for each codebook subframe uint8_t cbgain[16]; ///!< unsigned codebook gain for each codebook subframe uint8_t cindex[16]; ///!< codebook index for each codebook subframe /// @} -/// @defgroup qcelp_pitch_parameters QCELP pitch prediction parameters +/// @name QCELP pitch prediction parameters /// @{ uint8_t plag[4]; ///!< pitch lag for each pitch subframe uint8_t pfrac[4]; ///!< fractional pitch lag for each pitch subframe diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index 3ed821c81e..61c812c85d 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -738,11 +738,17 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int buf_size = avpkt->size; QCELPContext *q = avctx->priv_data; float *outbuffer = data; - int i; + int i, out_size; float quantized_lspf[10], lpc[10]; float gain[16]; float *formant_mem; + out_size = 160 * av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + if((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) { warn_insufficient_frame_quality(avctx, "bitrate cannot be determined."); @@ -837,9 +843,9 @@ erasure: memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf)); q->prev_bitrate = q->bitrate; - *data_size = 160 * sizeof(*outbuffer); + *data_size = out_size; - return *data_size; + return buf_size; } AVCodec ff_qcelp_decoder = diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 6eb836456c..6f0c896b56 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -76,6 +76,7 @@ do { \ #define SAMPLES_NEEDED_2(why) \ av_log (NULL,AV_LOG_INFO,"This file triggers some missing code. Please contact the developers.\nPosition: %s\n",why); +#define QDM2_MAX_FRAME_SIZE 512 typedef int8_t sb_int8_array[2][30][64]; @@ -168,7 +169,7 @@ typedef struct { /// I/O data const uint8_t *compressed_data; int compressed_size; - float output_buffer[1024]; + float output_buffer[QDM2_MAX_FRAME_SIZE * MPA_MAX_CHANNELS * 2]; /// Synthesis filter MPADSPContext mpadsp; @@ -880,9 +881,13 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l break; case 30: - if (BITS_LEFT(length,gb) >= 4) - samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)]; - else + if (BITS_LEFT(length,gb) >= 4) { + unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1); + if (index < FF_ARRAY_ELEMS(type30_dequant)) { + samples[0] = type30_dequant[index]; + } else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + } else samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); run = 1; @@ -896,8 +901,12 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l type34_predictor = samples[0]; type34_first = 0; } else { - samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor; - type34_predictor = samples[0]; + unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1); + if (index < FF_ARRAY_ELEMS(type34_delta)) { + samples[0] = type34_delta[index] / type34_div + type34_predictor; + type34_predictor = samples[0]; + } else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); } } else { samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); @@ -1229,6 +1238,11 @@ static void qdm2_decode_super_block (QDM2Context *q) for (i = 0; packet_bytes > 0; i++) { int j; + if (i>=FF_ARRAY_ELEMS(q->sub_packet_list_A)) { + SAMPLES_NEEDED_2("too many packet bytes"); + return; + } + q->sub_packet_list_A[i].next = NULL; if (i > 0) { @@ -1327,7 +1341,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * local_int_10 = 1 << (q->group_order - duration - 1); offset = 1; - while (1) { + while (get_bits_left(gb)>0) { if (q->superblocktype_2_3) { while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { offset = 1; @@ -1353,6 +1367,8 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * return; local_int_14 = (offset >> local_int_8); + if (local_int_14 >= FF_ARRAY_ELEMS(fft_level_index_table)) + return; if (q->nb_channels > 1) { channel = get_bits1(gb); @@ -1797,6 +1813,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata); extradata += 4; + if (s->channels > MPA_MAX_CHANNELS) + return AVERROR_INVALIDDATA; avctx->sample_rate = AV_RB32(extradata); extradata += 4; @@ -1811,6 +1829,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) extradata += 4; s->checksum_size = AV_RB32(extradata); + if (s->checksum_size >= 1U << 28) { + av_log(avctx, AV_LOG_ERROR, "data block size too large (%u)\n", s->checksum_size); + return AVERROR_INVALIDDATA; + } s->fft_order = av_log2(s->fft_size) + 1; s->fft_frame_size = 2 * s->fft_size; // complex has two floats @@ -1819,6 +1841,9 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) s->group_order = av_log2(s->group_size) + 1; s->frame_size = s->group_size / 16; // 16 iterations per super block + if (s->frame_size > QDM2_MAX_FRAME_SIZE) + return AVERROR_INVALIDDATA; + s->sub_sampling = s->fft_order - 7; s->frequency_range = 255 / (1 << (2 - s->sub_sampling)); @@ -1859,6 +1884,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); return -1; } + if (s->fft_size != (1 << (s->fft_order - 1))) { + av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size); + return AVERROR_INVALIDDATA; + } ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R); ff_mpadsp_init(&s->mpadsp); @@ -1887,6 +1916,9 @@ 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); + if((unsigned)frame_size > FF_ARRAY_ELEMS(q->output_buffer)/2) + return -1; + /* select input buffer */ q->compressed_data = in; q->compressed_size = q->checksum_size; @@ -1952,13 +1984,20 @@ static int qdm2_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; QDM2Context *s = avctx->priv_data; int16_t *out = data; - int i; + int i, out_size; if(!buf) return 0; if(buf_size < s->checksum_size) return -1; + out_size = 16 * s->channels * s->frame_size * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n", buf_size, buf, s->checksum_size, data, *data_size); @@ -1968,7 +2007,7 @@ static int qdm2_decode_frame(AVCodecContext *avctx, out += s->channels * s->frame_size; } - *data_size = (uint8_t*)out - (uint8_t*)data; + *data_size = out_size; return s->checksum_size; } diff --git a/libavcodec/qdm2_tablegen.h b/libavcodec/qdm2_tablegen.h index f215b15ffc..38adb97dc5 100644 --- a/libavcodec/qdm2_tablegen.h +++ b/libavcodec/qdm2_tablegen.h @@ -37,7 +37,7 @@ #include "libavcodec/qdm2_tables.h" #else static uint16_t softclip_table[HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1]; -static float noise_table[4096]; +static float noise_table[4096 + 20]; static uint8_t random_dequant_index[256][5]; static uint8_t random_dequant_type24[128][3]; static float noise_samples[128]; diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c index cd3146388e..6432728cb8 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -37,6 +37,7 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; QdrawContext * const a = avctx->priv_data; AVFrame * const p= (AVFrame*)&a->pic; @@ -59,6 +60,8 @@ static int decode_frame(AVCodecContext *avctx, outdata = a->pic.data[0]; + if (buf_end - buf < 0x68 + 4) + return AVERROR_INVALIDDATA; buf += 0x68; /* jump to palette */ colors = AV_RB32(buf); buf += 4; @@ -67,6 +70,8 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); return -1; } + if (buf_end - buf < (colors + 1) * 8) + return AVERROR_INVALIDDATA; pal = (uint32_t*)p->data[1]; for (i = 0; i <= colors; i++) { @@ -89,6 +94,8 @@ static int decode_frame(AVCodecContext *avctx, } p->palette_has_changed = 1; + if (buf_end - buf < 18) + return AVERROR_INVALIDDATA; buf += 18; /* skip unneeded data */ for (i = 0; i < avctx->height; i++) { int size, left, code, pix; @@ -100,6 +107,9 @@ static int decode_frame(AVCodecContext *avctx, out = outdata; size = AV_RB16(buf); /* size of packed line */ buf += 2; + if (buf_end - buf < size) + return AVERROR_INVALIDDATA; + left = size; next = buf + size; while (left > 0) { @@ -115,6 +125,8 @@ static int decode_frame(AVCodecContext *avctx, } else { /* copy */ if ((out + code) > (outdata + a->pic.linesize[0])) break; + if (buf_end - buf < code + 1) + return AVERROR_INVALIDDATA; memcpy(out, buf, code + 1); out += code + 1; buf += code + 1; diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 68232e28e3..24dfdb6452 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -168,7 +168,7 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, /* check motion vector */ if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (height - me_y - me_h < 0) || (height - me_y >= orig_height) || (filled + me_w > width) || (height - me_h < 0)) av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", me_x, me_y, me_w, me_h, filled, height); @@ -260,7 +260,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame * ref= (AVFrame*)&a->ref; uint8_t* outdata; int delta; - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if(ref->data[0]) avctx->release_buffer(avctx, ref); @@ -280,11 +279,11 @@ static int decode_frame(AVCodecContext *avctx, } /* make the palette available on the way out */ - if (pal) { + memcpy(a->pic.data[1], a->avctx->palctrl->palette, AVPALETTE_SIZE); + if (a->avctx->palctrl->palette_changed) { a->pic.palette_has_changed = 1; - memcpy(a->pal, pal, AVPALETTE_SIZE); + a->avctx->palctrl->palette_changed = 0; } - memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE); *data_size = sizeof(AVFrame); *(AVFrame*)data = a->pic; @@ -295,6 +294,10 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; + if (!avctx->palctrl) { + av_log(avctx, AV_LOG_FATAL, "Missing required palette via palctrl\n"); + return -1; + } avcodec_get_frame_defaults(&a->pic); avcodec_get_frame_defaults(&a->ref); a->avctx = avctx; diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index 2cc2de2e23..e093ba52b0 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -46,7 +46,6 @@ typedef struct QtrleContext { const unsigned char *buf; int size; - uint32_t pal[256]; } QtrleContext; #define CHECK_STREAM_PTR(n) \ @@ -127,6 +126,7 @@ static inline void qtrle_decode_2n4bpp(QtrleContext *s, int stream_ptr, while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (num_pixels * (s->buf[stream_ptr++] - 1)); + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -183,6 +183,7 @@ static void qtrle_decode_8bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1)); + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -236,6 +237,7 @@ static void qtrle_decode_16bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -285,6 +287,7 @@ static void qtrle_decode_24bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -336,6 +339,7 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -414,7 +418,7 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx) default: av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", avctx->bits_per_coded_sample); - break; + return AVERROR_INVALIDDATA; } avcodec_get_frame_defaults(&s->frame); @@ -464,6 +468,8 @@ static int qtrle_decode_frame(AVCodecContext *avctx, stream_ptr += 4; height = AV_RB16(&s->buf[stream_ptr]); stream_ptr += 4; + if (height > s->avctx->height - start_line) + goto done; } else { start_line = 0; height = s->avctx->height; @@ -513,15 +519,12 @@ static int qtrle_decode_frame(AVCodecContext *avctx, } if(has_palette) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - - if (pal) { - s->frame.palette_has_changed = 1; - memcpy(s->pal, pal, AVPALETTE_SIZE); - } - /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); + if (s->avctx->palctrl->palette_changed) { + s->frame.palette_has_changed = 1; + s->avctx->palctrl->palette_changed = 0; + } } done: diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 6874fc7034..cc742d15a1 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -866,6 +866,12 @@ static int init_pass2(MpegEncContext *s) assert(filter_size%2==1); /* fixed I/B QP relative to P mode */ + for(i=FFMAX(0, rcc->num_entries-300); inum_entries; i++){ + RateControlEntry *rce= &rcc->entry[i]; + + qscale[i]= get_diff_limited_q(s, rce, qscale[i]); + } + for(i=rcc->num_entries-1; i>=0; i--){ RateControlEntry *rce= &rcc->entry[i]; diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index 503351e68a..2c38925a44 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -151,6 +151,9 @@ static int raw_decode(AVCodecContext *avctx, frame->top_field_first = context->tff; } + if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) + return -1; + //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) if (context->buffer) { int i; @@ -175,22 +178,15 @@ static int raw_decode(AVCodecContext *avctx, avctx->codec_tag == MKTAG('A', 'V', 'u', 'p')) buf += buf_size - context->length; - if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) - return -1; - avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); if((avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length) || (avctx->pix_fmt!=PIX_FMT_PAL8 && (av_pix_fmt_descriptors[avctx->pix_fmt].flags & PIX_FMT_PAL))){ frame->data[1]= context->palette; } - if (avctx->pix_fmt == PIX_FMT_PAL8) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - - if (pal) { - memcpy(frame->data[1], pal, AVPALETTE_SIZE); - frame->palette_has_changed = 1; - } + if (avctx->palctrl && avctx->palctrl->palette_changed) { + memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + avctx->palctrl->palette_changed = 0; } if(avctx->pix_fmt==PIX_FMT_BGR24 && ((frame->linesize[0]+3)&~3)*avctx->height <= buf_size) frame->linesize[0] = (frame->linesize[0]+3)&~3; diff --git a/libavcodec/resample.c b/libavcodec/resample.c index 33413dbeaf..d53c7315b1 100644 --- a/libavcodec/resample.c +++ b/libavcodec/resample.c @@ -275,6 +275,17 @@ ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, return s; } +#if FF_API_AUDIO_OLD +ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate) +{ + return av_audio_resample_init(output_channels, input_channels, + output_rate, input_rate, + AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, + TAPS, 10, 0, 0.8); +} +#endif + /* resample audio. 'nb_samples' is the number of input samples */ /* XXX: optimize it ! */ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) @@ -326,9 +337,9 @@ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_sampl if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) { output_bak = output; - if (!s->buffer_size[1] || s->buffer_size[1] < lenout) { + if (!s->buffer_size[1] || s->buffer_size[1] < 2*lenout) { av_free(s->buffer[1]); - s->buffer_size[1] = lenout; + s->buffer_size[1] = 2*lenout; s->buffer[1] = av_malloc(s->buffer_size[1]); if (!s->buffer[1]) { av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); diff --git a/libavcodec/resample2.c b/libavcodec/resample2.c index b940059d84..5c425587ab 100644 --- a/libavcodec/resample2.c +++ b/libavcodec/resample2.c @@ -207,8 +207,10 @@ AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; - c->src_incr= out_rate; - c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; + if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2)) + goto error; + c->ideal_dst_incr= c->dst_incr; + c->index= -phase_count*((c->filter_length-1)/2); return c; @@ -246,10 +248,9 @@ int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int dst[dst_index] = src[index2>>32]; index2 += incr; } - frac += dst_index * dst_incr_frac; index += dst_index * dst_incr; - index += frac / c->src_incr; - frac %= c->src_incr; + index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr; + frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr; }else{ for(dst_index=0; dst_index < dst_size; dst_index++){ FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask); diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index f0977f6491..4e34231aa4 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -157,6 +157,12 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) RoqContext *s = avctx->priv_data; s->avctx = avctx; + + if (avctx->width%16 || avctx->height%16) { + av_log_ask_for_sample(avctx, "dimensions not being a multiple of 16 are unsupported\n"); + return AVERROR_PATCHWELCOME; + } + s->width = avctx->width; s->height = avctx->height; avcodec_get_frame_defaults(&s->frames[0]); diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 9030affb31..39088fe207 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -941,6 +941,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 12558563c6..f7240ab330 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -83,7 +83,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; @@ -139,6 +139,7 @@ static void rpza_decode_stream(RpzaContext *s) colorA = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; while (n_blocks--) { + ADVANCE_BLOCK() block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ @@ -147,7 +148,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); } break; @@ -183,7 +183,10 @@ static void rpza_decode_stream(RpzaContext *s) color4[1] |= ((11 * ta + 21 * tb) >> 5); color4[2] |= ((21 * ta + 11 * tb) >> 5); + if (s->size - stream_ptr < n_blocks * 4) + return; while (n_blocks--) { + ADVANCE_BLOCK(); block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { index = s->buf[stream_ptr++]; @@ -194,12 +197,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) + return; + ADVANCE_BLOCK(); block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ @@ -213,7 +218,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); break; /* Unknown opcode */ diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h index 4bcb9f70ca..73d41f481d 100644 --- a/libavcodec/rtjpeg.h +++ b/libavcodec/rtjpeg.h @@ -25,6 +25,9 @@ #include #include "dsputil.h" +#define RTJPEG_FILE_VERSION 0 +#define RTJPEG_HEADER_SIZE 12 + typedef struct { int w, h; DSPContext *dsp; diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 2f822a8ac2..17f1357718 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -362,6 +362,11 @@ static int rv20_decode_picture_header(MpegEncContext *s) f= get_bits(&s->gb, av_log2(v)+1); 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{ @@ -498,7 +503,7 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; - h263_decode_init_vlc(s); + ff_h263_decode_init_vlc(s); /* init rv vlc */ if (!done) { @@ -559,8 +564,14 @@ static int rv10_decode_packet(AVCodecContext *avctx, if(MPV_frame_start(s, avctx) < 0) return -1; ff_er_frame_start(s); + } else { + if (s->current_picture_ptr->pict_type != s->pict_type) { + av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); + return -1; + } } + av_dlog(avctx, "qscale=%d\n", s->qscale); /* default quantization values */ @@ -666,8 +677,12 @@ static int rv10_decode_frame(AVCodecContext *avctx, if(!avctx->slice_count){ slice_count = (*buf++) + 1; + buf_size--; slices_hdr = buf + 4; buf += 8 * slice_count; + buf_size -= 8 * slice_count; + if (buf_size <= 0) + return AVERROR_INVALIDDATA; }else slice_count = avctx->slice_count; @@ -706,7 +721,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } - return buf_size; + return avpkt->size; } AVCodec ff_rv10_decoder = { diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index b43859b9cb..600656b466 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -51,6 +51,11 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn skip_bits1(gb); si->pts = get_bits(gb, 13); rpr = get_bits(gb, r->rpr); + if (r->s.avctx->extradata_size < 8 + rpr*2) { + av_log(r->s.avctx, AV_LOG_WARNING, + "Extradata does not contain selected resolution\n"); + rpr = 0; + } if(rpr){ w = r->s.avctx->extradata[6 + rpr*2] << 2; h = r->s.avctx->extradata[7 + rpr*2] << 2; @@ -74,7 +79,7 @@ static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){ for(j = 0; j < 4; j+= 2){ int code = svq3_get_ue_golomb(gb) << 1; - if(code >= 81*2){ + if(code >= 81U*2U){ av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); return -1; } @@ -103,7 +108,7 @@ static int rv30_decode_mb_info(RV34DecContext *r) GetBitContext *gb = &s->gb; int code = svq3_get_ue_golomb(gb); - if(code > 11){ + if(code > 11U){ av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); return -1; } @@ -256,6 +261,7 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx) 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); + return AVERROR(EINVAL); } r->parse_slice_header = rv30_parse_slice_header; r->decode_intra_types = rv30_decode_intra_types; diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index ae9ae1084f..e5968d9180 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -62,8 +62,10 @@ static const int rv34_mb_type_to_lavc[12] = { static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES]; +static int rv34_decode_mv(RV34DecContext *r, int block_type); + /** - * @defgroup vlc RV30/40 VLC generating functions + * @name RV30/40 VLC generating functions * @{ */ @@ -171,7 +173,7 @@ static av_cold void rv34_init_tables(void) /** - * @defgroup transform RV30/40 inverse transform functions + * @name RV30/40 inverse transform functions * @{ */ @@ -246,7 +248,7 @@ static void rv34_inv_transform_noround(DCTELEM *block){ /** - * @defgroup block RV30/40 4x4 block decoding functions + * @name RV30/40 4x4 block decoding functions * @{ */ @@ -393,7 +395,7 @@ static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q) /** - * @defgroup rv3040_bitstream RV30/40 bitstream parsing + * @name RV30/40 bitstream parsing * @{ */ @@ -432,10 +434,76 @@ static inline int rv34_decode_dquant(GetBitContext *gb, int quant) return get_bits(gb, 5); } +/** + * Decode macroblock header and return CBP in case of success, -1 otherwise. + */ +static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int i, t; + + if(!r->si.type){ + r->is16 = get_bits1(gb); + if(!r->is16 && !r->rv30){ + if(!get_bits1(gb)) + av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); + } + s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; + r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; + }else{ + r->block_type = r->decode_mb_info(r); + if(r->block_type == -1) + return -1; + s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; + r->mb_type[mb_pos] = r->block_type; + if(r->block_type == RV34_MB_SKIP){ + if(s->pict_type == AV_PICTURE_TYPE_P) + r->mb_type[mb_pos] = RV34_MB_P_16x16; + if(s->pict_type == AV_PICTURE_TYPE_B) + r->mb_type[mb_pos] = RV34_MB_B_DIRECT; + } + r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); + rv34_decode_mv(r, r->block_type); + if(r->block_type == RV34_MB_SKIP){ + fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0])); + return 0; + } + r->chroma_vlc = 1; + r->luma_vlc = 0; + } + if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ + if(r->is16){ + t = get_bits(gb, 2); + fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0])); + r->luma_vlc = 2; + }else{ + if(r->decode_intra_types(r, gb, intra_types) < 0) + return -1; + r->luma_vlc = 1; + } + r->chroma_vlc = 0; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); + }else{ + for(i = 0; i < 16; i++) + intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); + if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ + r->is16 = 1; + r->chroma_vlc = 1; + r->luma_vlc = 2; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); + } + } + + return rv34_decode_cbp(gb, r->cur_vlcs, r->is16); +} + /** @} */ //bitstream functions /** - * @defgroup mv motion vector related code (prediction, reconstruction, motion compensation) + * @name motion vector related code (prediction, reconstruction, motion compensation) * @{ */ @@ -885,7 +953,7 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) /** @} */ // mv group /** - * @defgroup recons Macroblock reconstruction functions + * @name Macroblock reconstruction functions * @{ */ /** mapping of RV30/40 intra prediction types to standard H.264 types */ @@ -1027,79 +1095,6 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c } } -/** @} */ // recons group - -/** - * @addtogroup bitstream - * Decode macroblock header and return CBP in case of success, -1 otherwise. - */ -static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int i, t; - - if(!r->si.type){ - r->is16 = get_bits1(gb); - if(!r->is16 && !r->rv30){ - if(!get_bits1(gb)) - av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); - } - s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; - r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; - }else{ - r->block_type = r->decode_mb_info(r); - if(r->block_type == -1) - return -1; - s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; - r->mb_type[mb_pos] = r->block_type; - if(r->block_type == RV34_MB_SKIP){ - if(s->pict_type == AV_PICTURE_TYPE_P) - r->mb_type[mb_pos] = RV34_MB_P_16x16; - if(s->pict_type == AV_PICTURE_TYPE_B) - r->mb_type[mb_pos] = RV34_MB_B_DIRECT; - } - r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); - rv34_decode_mv(r, r->block_type); - if(r->block_type == RV34_MB_SKIP){ - fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0])); - return 0; - } - r->chroma_vlc = 1; - r->luma_vlc = 0; - } - if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ - if(r->is16){ - t = get_bits(gb, 2); - fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0])); - r->luma_vlc = 2; - }else{ - if(r->decode_intra_types(r, gb, intra_types) < 0) - return -1; - r->luma_vlc = 1; - } - r->chroma_vlc = 0; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); - }else{ - for(i = 0; i < 16; i++) - intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); - if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ - r->is16 = 1; - r->chroma_vlc = 1; - r->luma_vlc = 2; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); - } - } - - return rv34_decode_cbp(gb, r->cur_vlcs, r->is16); -} - -/** - * @addtogroup recons - * @{ - */ /** * mask for retrieving all bits in coded block pattern * corresponding to one 8x8 block @@ -1109,6 +1104,8 @@ static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) #define U_CBP_MASK 0x0F0000 #define V_CBP_MASK 0xF00000 +/** @} */ // recons group + static void rv34_apply_differences(RV34DecContext *r, int cbp) { @@ -1283,6 +1280,14 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { if(s->width != r->si.width || s->height != r->si.height){ + + if (HAVE_THREADS && + (s->avctx->active_thread_type & FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height changing with " + "frame threading is", 0); + return AVERROR_PATCHWELCOME; + } + av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height); MPV_common_end(s); s->width = r->si.width; @@ -1308,6 +1313,17 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int r->next_pts = r->cur_pts; } s->mb_x = s->mb_y = 0; + } else { + int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I; + + if (slice_type != s->pict_type) { + av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); + return AVERROR_INVALIDDATA; + } + if (s->width != r->si.width || s->height != r->si.height) { + av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n"); + return AVERROR_INVALIDDATA; + } } r->si.end = end; @@ -1439,25 +1455,41 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, slice_count = (*buf++) + 1; slices_hdr = buf + 4; buf += 8 * slice_count; + buf_size -= 1 + 8 * slice_count; }else slice_count = avctx->slice_count; //parse first slice header to check whether this frame can be decoded - if(get_slice_offset(avctx, slices_hdr, 0) > buf_size){ - av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n"); - return -1; + if(get_slice_offset(avctx, slices_hdr, 0) < 0 || + get_slice_offset(avctx, slices_hdr, 0) > buf_size){ + av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); + return AVERROR_INVALIDDATA; } - init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), buf_size-get_slice_offset(avctx, slices_hdr, 0)); + init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8); if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){ av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n"); - return -1; + return AVERROR_INVALIDDATA; } - if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == AV_PICTURE_TYPE_B) - return -1; + if ((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && + si.type == AV_PICTURE_TYPE_B) { + av_log(avctx, AV_LOG_ERROR, "Invalid decoder state: B-frame without " + "reference data.\n"); + return AVERROR_INVALIDDATA; + } + +#if FF_API_HURRY_UP + /* skip b frames if we are in a hurry */ + if(avctx->hurry_up && si.type==FF_B_TYPE) return buf_size; +#endif + if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B) || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I) - || avctx->skip_frame >= AVDISCARD_ALL) + || avctx->skip_frame >= AVDISCARD_ALL) return avpkt->size; +#if FF_API_HURRY_UP + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) return buf_size; +#endif for(i=0; i buf_size){ - av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n"); + if(offset < 0 || offset > buf_size){ + av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); break; } r->si.end = s->mb_width * s->mb_height; if(i+1 < slice_count){ + if (get_slice_offset(avctx, slices_hdr, i+1) < 0 || + get_slice_offset(avctx, slices_hdr, i+1) > buf_size) { + av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); + break; + } init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8); if(r->parse_slice_header(r, &r->s.gb, &si) < 0){ if(i+2 < slice_count) @@ -1483,13 +1520,17 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, }else r->si.end = si.start; } + if (size < 0 || size > buf_size - offset) { + av_log(avctx, AV_LOG_ERROR, "Slice size is invalid\n"); + break; + } last = rv34_decode_slice(r, r->si.end, buf + offset, size); s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start; if(last) break; } - if(last){ + if(last && s->current_picture_ptr){ if(r->loop_filter) r->loop_filter(r, s->mb_height - 1); ff_er_frame_end(s); @@ -1506,7 +1547,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, } s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } - return buf_size; + return avpkt->size; } av_cold int ff_rv34_decode_end(AVCodecContext *avctx) diff --git a/libavcodec/rv34data.h b/libavcodec/rv34data.h index 2155084d09..3ba1beb9bf 100644 --- a/libavcodec/rv34data.h +++ b/libavcodec/rv34data.h @@ -123,7 +123,7 @@ static const uint8_t rv34_quant_to_vlc_set[2][31] = { /** * table for obtaining the quantizer difference - * @todo Use with modified_quant_tab from h263data.h. + * @todo Use with ff_modified_quant_tab from h263data.h. */ static const uint8_t rv34_dquant_tab[2][32]={ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index 54d786a3a6..842f01af02 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -231,8 +231,11 @@ static int rv40_decode_mb_info(RV34DecContext *r) int blocks[RV34_MB_TYPES] = {0}; int count = 0; - if(!r->s.mb_skip_run) + if(!r->s.mb_skip_run) { r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; + if(r->s.mb_skip_run > (unsigned)s->mb_num) + return -1; + } if(--r->s.mb_skip_run) return RV34_MB_SKIP; diff --git a/libavcodec/rv40data.h b/libavcodec/rv40data.h index 7912919ba1..436afa84e2 100644 --- a/libavcodec/rv40data.h +++ b/libavcodec/rv40data.h @@ -65,7 +65,7 @@ static const uint8_t rv40_luma_dc_quant[2][32] = { }; /** - * @defgroup loopfilter coefficients used by the RV40 loop filter + * @name Coefficients used by the RV40 loop filter * @{ */ /** diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h index 82a996fdc6..69c847ac15 100644 --- a/libavcodec/sbr.h +++ b/libavcodec/sbr.h @@ -42,7 +42,7 @@ typedef struct { uint8_t bs_xover_band; /** - * @defgroup bs_header_extra_1 Variables associated with bs_header_extra_1 + * @name Variables associated with bs_header_extra_1 * @{ */ uint8_t bs_freq_scale; @@ -58,7 +58,7 @@ typedef struct { */ typedef struct { /** - * @defgroup aac_bitstream Main bitstream data variables + * @name Main bitstream data variables * @{ */ unsigned bs_frame_class; @@ -74,7 +74,7 @@ typedef struct { /** @} */ /** - * @defgroup state State variables + * @name State variables * @{ */ DECLARE_ALIGNED(16, float, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE]; @@ -116,7 +116,7 @@ typedef struct { SpectrumParameters spectrum_params; int bs_amp_res_header; /** - * @defgroup bs_header_extra_2 variables associated with bs_header_extra_2 + * @name Variables associated with bs_header_extra_2 * @{ */ unsigned bs_limiter_bands; diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index f593d0a164..2f7c13cedc 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -78,9 +78,10 @@ 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]; int32_t *offset[MAX_CHANNELS]; int *coeffs; uint8_t *bitstream; @@ -113,23 +114,31 @@ static int allocate_buffers(ShortenContext *s) { int i, chan; int *coeffs; + void *tmp_ptr; for (chan=0; chanchannels; chan++) { if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){ av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n"); - return -1; + return AVERROR_INVALIDDATA; } if(s->blocksize + s->nwrap >= UINT_MAX/sizeof(int32_t) || s->blocksize + s->nwrap <= (unsigned)s->nwrap){ av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n"); - return -1; + return AVERROR_INVALIDDATA; } - s->offset[chan] = 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; - s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) * + sizeof(s->decoded_base[0][0])); + if (!tmp_ptr) + return AVERROR(ENOMEM); + s->decoded_base[chan] = tmp_ptr; for (i=0; inwrap; i++) - s->decoded[chan][i] = 0; - s->decoded[chan] += s->nwrap; + s->decoded_base[chan][i] = 0; + s->decoded[chan] = s->decoded_base[chan] + s->nwrap; } coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs)); @@ -155,7 +164,7 @@ static void fix_bitshift(ShortenContext *s, int32_t *buffer) if (s->bitshift != 0) for (i = 0; i < s->blocksize; i++) - buffer[s->nwrap + i] <<= s->bitshift; + buffer[i] <<= s->bitshift; } @@ -200,14 +209,14 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header init_get_bits(&hb, header, header_size*8); if (get_le32(&hb) != MKTAG('R','I','F','F')) { av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(&hb, 32); /* chunk_size */ if (get_le32(&hb) != MKTAG('W','A','V','E')) { av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); - return -1; + return AVERROR_INVALIDDATA; } while (get_le32(&hb) != MKTAG('f','m','t',' ')) { @@ -218,7 +227,7 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header if (len < 16) { av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); - return -1; + return AVERROR_INVALIDDATA; } wave_format = get_le16(&hb); @@ -228,7 +237,7 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header break; default: av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); - return -1; + return AVERROR(ENOSYS); } avctx->channels = get_le16(&hb); @@ -239,7 +248,7 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header if (avctx->bits_per_coded_sample != 16) { av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); - return -1; + return AVERROR(ENOSYS); } len -= 16; @@ -284,8 +293,15 @@ static int shorten_decode_frame(AVCodecContext *avctx, int i, input_buf_size = 0; int16_t *samples = data; if(s->max_framesize == 0){ + void *tmp_ptr; s->max_framesize= 1024; // should hopefully be enough for the first header - s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); + tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, + s->max_framesize); + if (!tmp_ptr) { + av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n"); + return AVERROR(ENOMEM); + } + s->bitstream = tmp_ptr; } if(1 && s->max_framesize){//FIXME truncated @@ -326,8 +342,13 @@ static int shorten_decode_frame(AVCodecContext *avctx, s->internal_ftype = get_uint(s, TYPESIZE); s->channels = get_uint(s, CHANSIZE); - if (s->channels > MAX_CHANNELS) { + if (!s->channels) { + av_log(s->avctx, AV_LOG_ERROR, "No channels reported\n"); + return AVERROR_INVALIDDATA; + } + if (s->channels <= 0 || s->channels > MAX_CHANNELS) { av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); + s->channels = 0; return -1; } @@ -467,6 +488,12 @@ static int shorten_decode_frame(AVCodecContext *avctx, s->cur_chan++; if (s->cur_chan == s->channels) { + int out_size = s->blocksize * s->channels * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded); s->cur_chan = 0; goto frame_done; @@ -483,9 +510,15 @@ static int shorten_decode_frame(AVCodecContext *avctx, case FN_BITSHIFT: s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); break; - case FN_BLOCKSIZE: - s->blocksize = get_uint(s, av_log2(s->blocksize)); + 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; + } + s->blocksize = blocksize; break; + } case FN_QUIT: *data_size = 0; return buf_size; @@ -506,7 +539,7 @@ frame_done: av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); s->bitstream_size=0; s->bitstream_index=0; - return -1; + return AVERROR_INVALIDDATA; } if (s->bitstream_size) { s->bitstream_index += i; @@ -522,8 +555,8 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx) int i; for (i = 0; i < s->channels; i++) { - s->decoded[i] -= s->nwrap; - av_freep(&s->decoded[i]); + s->decoded[i] = NULL; + av_freep(&s->decoded_base[i]); av_freep(&s->offset[i]); } av_freep(&s->bitstream); diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 9befe8a158..bd7d22388a 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -194,14 +194,16 @@ static void decode_parameters(SiprParameters* parms, GetBitContext *pgb, { int i, j; - parms->ma_pred_switch = get_bits(pgb, p->ma_predictor_bits); + if (p->ma_predictor_bits) + parms->ma_pred_switch = get_bits(pgb, p->ma_predictor_bits); for (i = 0; i < 5; i++) parms->vq_indexes[i] = get_bits(pgb, p->vq_indexes_bits[i]); for (i = 0; i < p->subframe_count; i++) { parms->pitch_delay[i] = get_bits(pgb, p->pitch_delay_bits[i]); - parms->gp_index[i] = get_bits(pgb, p->gp_index_bits); + if (p->gp_index_bits) + parms->gp_index[i] = get_bits(pgb, p->gp_index_bits); for (j = 0; j < p->number_of_fc_indexes; j++) parms->fc_indexes[i][j] = get_bits(pgb, p->fc_index_bits[j]); @@ -509,7 +511,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *datap, GetBitContext gb; float *data = datap; int subframe_size = ctx->mode == MODE_16k ? L_SUBFR_16k : SUBFR_SIZE; - int i; + int i, out_size; ctx->avctx = avctx; if (avpkt->size < (mode_par->bits_per_frame >> 3)) { @@ -520,7 +522,11 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *datap, *data_size = 0; return -1; } - if (*data_size < subframe_size * mode_par->subframe_count * sizeof(float)) { + + out_size = mode_par->frames_per_packet * subframe_size * + mode_par->subframe_count * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { av_log(avctx, AV_LOG_ERROR, "Error processing packet: output buffer (%d) too small\n", *data_size); @@ -542,8 +548,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *datap, data += subframe_size * mode_par->subframe_count; } - *data_size = mode_par->frames_per_packet * subframe_size * - mode_par->subframe_count * sizeof(float); + *data_size = out_size; return mode_par->bits_per_frame >> 3; } diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index b8eab837ff..bf73a79010 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -127,18 +127,20 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref */ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) { + if (hc->current + 1 >= hc->length) { + av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); + return -1; + } if(!get_bits1(gb)){ //Leaf int val, i1, i2, b1, b2; - if(hc->current >= hc->length){ - av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); - return -1; - } b1 = get_bits_count(gb); - i1 = get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3); + i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; b1 = get_bits_count(gb) - b1; b2 = get_bits_count(gb); - i2 = get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3); + i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) : 0; b2 = get_bits_count(gb) - b2; + if (i1 < 0 || i2 < 0) + return -1; val = ctx->recode1[i1] | (ctx->recode2[i2] << 8); if(val == ctx->escapes[0]) { ctx->last[0] = hc->current; @@ -154,7 +156,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx hc->values[hc->current++] = val; return 1; } else { //Node - int r = 0, t; + int r = 0, r_new, t; t = hc->current++; r = smacker_decode_bigtree(gb, hc, ctx); @@ -162,8 +164,10 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx return r; hc->values[t] = SMK_NODE | r; r++; - r += smacker_decode_bigtree(gb, hc, ctx); - return r; + r_new = smacker_decode_bigtree(gb, hc, ctx); + if (r_new < 0) + return r_new; + return r + r_new; } } @@ -178,6 +182,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int VLC vlc[2]; int escapes[3]; DBCtx ctx; + int err = 0; if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); @@ -251,7 +256,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); - smacker_decode_bigtree(gb, &huff, &ctx); + if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + err = -1; skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; @@ -270,7 +276,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int av_free(tmp2.lengths); av_free(tmp2.values); - return 0; + return err; } static int decode_header_trees(SmackVContext *smk) { @@ -290,7 +296,8 @@ static int decode_header_trees(SmackVContext *smk) { smk->mmap_tbl[0] = 0; smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; } else { - smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); + if (smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size)) + return -1; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); @@ -298,7 +305,8 @@ static int decode_header_trees(SmackVContext *smk) { smk->mclr_tbl[0] = 0; smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; } else { - smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); + if (smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size)) + return -1; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); @@ -306,7 +314,8 @@ static int decode_header_trees(SmackVContext *smk) { smk->full_tbl[0] = 0; smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; } else { - smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); + if (smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size)) + return -1; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); @@ -314,7 +323,8 @@ static int decode_header_trees(SmackVContext *smk) { smk->type_tbl[0] = 0; smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; } else { - smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); + if (smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size)) + return -1; } return 0; @@ -523,8 +533,8 @@ static av_cold int decode_init(AVCodecContext *avctx) return -1; } - decode_header_trees(c); - + if (decode_header_trees(c)) + return -1; return 0; } @@ -554,6 +564,10 @@ static av_cold int decode_end(AVCodecContext *avctx) static av_cold int smka_decode_init(AVCodecContext *avctx) { + if (avctx->channels < 1 || avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n"); + return AVERROR(EINVAL); + } avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16; return 0; @@ -577,6 +591,11 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int bits, stereo; int pred[2] = {0, 0}; + if (buf_size <= 4) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + unp_size = AV_RL32(buf); init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); @@ -592,6 +611,14 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); return -1; } + if (stereo ^ (avctx->channels != 1)) { + av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); + return AVERROR(EINVAL); + } + if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) { + av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); + return AVERROR(EINVAL); + } memset(vlc, 0, sizeof(VLC) * 4); memset(h, 0, sizeof(HuffContext) * 4); @@ -618,10 +645,10 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) - pred[i] = av_bswap16(get_bits(&gb, 16)); - for(i = 0; i < stereo; i++) + pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); + for(i = 0; i <= stereo; i++) *samples++ = pred[i]; - for(i = 0; i < unp_size / 2; i++) { + for(; i < unp_size / 2; i++) { if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); @@ -653,9 +680,9 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); - for(i = 0; i < stereo; i++) + for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; - for(i = 0; i < unp_size; i++) { + for(; i < unp_size; i++) { if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); diff --git a/libavcodec/smc.c b/libavcodec/smc.c index ce5b72a2a3..ff185fbc3c 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -54,7 +54,6 @@ typedef struct SmcContext { unsigned char color_quads[COLORS_PER_TABLE * CQUAD]; unsigned char color_octets[COLORS_PER_TABLE * COCTET]; - uint32_t pal[256]; } SmcContext; #define GET_BLOCK_COUNT() \ @@ -69,7 +68,7 @@ typedef struct SmcContext { row_ptr += stride * 4; \ } \ total_blocks--; \ - if (total_blocks < 0) \ + if (total_blocks < 0 + !!n_blocks) \ { \ av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \ return; \ @@ -111,7 +110,11 @@ static void smc_decode_stream(SmcContext *s) int color_octet_index = 0; /* make the palette available */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); + if (s->avctx->palctrl->palette_changed) { + s->frame.palette_has_changed = 1; + s->avctx->palctrl->palette_changed = 0; + } chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF; stream_ptr += 4; @@ -438,7 +441,6 @@ static int smc_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; SmcContext *s = avctx->priv_data; - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); s->buf = buf; s->size = buf_size; @@ -451,11 +453,6 @@ static int smc_decode_frame(AVCodecContext *avctx, return -1; } - if (pal) { - s->frame.palette_has_changed = 1; - memcpy(s->pal, pal, AVPALETTE_SIZE); - } - smc_decode_stream(s); *data_size = sizeof(AVFrame); diff --git a/libavcodec/snow.c b/libavcodec/snow.c index 43a71904eb..cf3e5adc6b 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -1917,8 +1917,6 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ int p,x,y; - assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE)); - for(p=0; p<3; p++){ int is_chroma= !!p; int w= s->avctx->width >>is_chroma; @@ -1975,7 +1973,7 @@ static int frame_start(SnowContext *s){ int w= s->avctx->width; //FIXME round up to x16 ? int h= s->avctx->height; - if(s->current_picture.data[0]){ + if(s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)){ s->dsp.draw_edges(s->current_picture.data[0], s->current_picture.linesize[0], w , h , EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); @@ -2301,7 +2299,7 @@ static av_cold int encode_init(AVCodecContext *avctx) s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t)); - h263_encode_init(&s->m); //mv_penalty + ff_h263_encode_init(&s->m); //mv_penalty s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1); diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index aa73f4c7bf..b6f2dade0c 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -110,7 +110,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, for (j=sptr-2; j>=0; j--) if (stack[j].param[i][0]) { out += snprintf(out, out_end-out, - stack[j].param[i]); + "%s", stack[j].param[i]); break; } } else { @@ -146,7 +146,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, for (i=0; idata; + const uint8_t *buf_end = avpkt->data + avpkt->size; SUNRASTContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; @@ -53,6 +54,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, uint8_t *ptr; const uint8_t *bufstart = buf; + if (avpkt->size < 32) + return AVERROR_INVALIDDATA; + if (AV_RB32(buf) != 0x59a66a95) { av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); return -1; @@ -64,13 +68,14 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, type = AV_RB32(buf+20); maptype = AV_RB32(buf+24); maplength = AV_RB32(buf+28); + buf += 32; - if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); + if (type < RT_OLD || type > RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); return -1; } - if (type > RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); + if (av_image_check_size(w, h, 0, avctx)) { + av_log(avctx, AV_LOG_ERROR, "invalid image size\n"); return -1; } if (maptype & ~1) { @@ -78,7 +83,10 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return -1; } - buf += 32; + if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); + return -1; + } switch (depth) { case 1: @@ -98,8 +106,6 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, if (p->data[0]) avctx->release_buffer(avctx, p); - if (av_image_check_size(w, h, 0, avctx)) - return -1; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); if (avctx->get_buffer(avctx, p) < 0) { @@ -109,6 +115,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, p->pict_type = AV_PICTURE_TYPE_I; + if (buf_end - buf < maplength) + return AVERROR_INVALIDDATA; + if (depth != 8 && maplength) { av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); @@ -143,8 +152,11 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, uint8_t *end = ptr + h*stride; x = 0; - while (ptr != end) { + while (ptr != end && buf < buf_end) { run = 1; + if (buf_end - buf < 1) + return AVERROR_INVALIDDATA; + if ((value = *buf++) == 0x80) { run = *buf++ + 1; if (run != 1) @@ -163,6 +175,8 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, } } else { for (y=0; y -extern const uint8_t mvtab[33][2]; +extern const uint8_t ff_mvtab[33][2]; static VLC svq1_block_type; static VLC svq1_motion_component; @@ -658,11 +658,15 @@ static int svq1_decode_frame(AVCodecContext *avctx, av_dlog(s->avctx, "Error in svq1_decode_frame_header %i\n",result); return result; } + avcodec_set_dimensions(avctx, s->width, s->height); //FIXME this avoids some confusion for "B frames" without 2 references //this should be removed after libavcodec can handle more flexible picture types & ordering if(s->pict_type==AV_PICTURE_TYPE_B && s->last_picture_ptr==NULL) return buf_size; +#if FF_API_HURRY_UP + if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return buf_size; +#endif if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) @@ -767,8 +771,8 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) &ff_svq1_block_type_vlc[0][0], 2, 1, 6); INIT_VLC_STATIC(&svq1_motion_component, 7, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 176); + &ff_mvtab[0][1], 2, 1, + &ff_mvtab[0][0], 2, 1, 176); for (i = 0; i < 6; i++) { static const uint8_t sizes[2][6] = {{14, 10, 14, 18, 16, 18}, {10, 10, 14, 14, 14, 16}}; diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index edd6029209..7a387a4bb0 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -406,7 +406,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane int mx, my, pred_x, pred_y, dxy; int16_t *motion_ptr; - motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); + motion_ptr= ff_h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ for(i=0; i<6; i++) init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); @@ -496,7 +496,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); - h263_encode_init(&s->m); //mv_penalty + ff_h263_encode_init(&s->m); //mv_penalty return 0; } diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 30cd0f102f..6080eca2fd 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -221,7 +221,7 @@ static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block, for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) { - if (vlc == INVALID_VLC) + if (vlc < 0) return -1; sign = (vlc & 0x1) - 1; @@ -239,7 +239,7 @@ static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block, level = ((vlc + 9) >> 2) - run; } } else { - if (vlc < 16) { + if (vlc < 16U) { run = svq3_dct_tables[intra][vlc].run; level = svq3_dct_tables[intra][vlc].level; } else if (intra) { @@ -569,7 +569,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) for (i = 0; i < 16; i+=2) { vlc = svq3_get_ue_golomb(&s->gb); - if (vlc >= 25){ + if (vlc >= 25U){ av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc); return -1; } @@ -612,7 +612,7 @@ 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)) == -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; } @@ -641,7 +641,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) } if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) { - if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48){ + if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48U){ av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc); return -1; } @@ -651,7 +651,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { s->qscale += svq3_get_se_golomb(&s->gb); - if (s->qscale > 31){ + if (s->qscale > 31U){ av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); return -1; } @@ -711,7 +711,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) s->current_picture.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) { - h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8); + h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1); } return 0; @@ -755,7 +755,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) skip_bits_long(&s->gb, 0); } - if ((i = svq3_get_ue_golomb(&s->gb)) == INVALID_VLC || i >= 3){ + if ((i = svq3_get_ue_golomb(&s->gb)) >= 3U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i); return -1; } @@ -811,7 +811,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) MpegEncContext *s = &h->s; int m; unsigned char *extradata; + unsigned char *extradata_end; unsigned int size; + int marker_found = 0; if (ff_h264_decode_init(avctx) < 0) return -1; @@ -832,19 +834,26 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) /* prowl for the "SEQH" marker in the extradata */ extradata = (unsigned char *)avctx->extradata; - for (m = 0; m < avctx->extradata_size; m++) { - if (!memcmp(extradata, "SEQH", 4)) - break; - extradata++; + extradata_end = avctx->extradata + avctx->extradata_size; + if (extradata) { + for (m = 0; m + 8 < avctx->extradata_size; m++) { + if (!memcmp(extradata, "SEQH", 4)) { + marker_found = 1; + break; + } + extradata++; + } } /* if a match was found, parse the extra data */ - if (extradata && !memcmp(extradata, "SEQH", 4)) { + if (marker_found) { GetBitContext gb; int frame_size_code; size = AV_RB32(&extradata[4]); + if (size > extradata_end - extradata - 8) + return AVERROR_INVALIDDATA; init_get_bits(&gb, extradata + 8, size*8); /* 'frame size code' and optional 'width, height' */ @@ -986,6 +995,14 @@ static int svq3_decode_frame(AVCodecContext *avctx, /* Skip B-frames if we do not have reference frames. */ if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B) return 0; +#if FF_API_HURRY_UP + /* Skip B-frames if we are in a hurry. */ + if (avctx->hurry_up && s->pict_type == FF_B_TYPE) + return 0; + /* Skip everything if we are in a hurry >= 5. */ + if (avctx->hurry_up >= 5) + return 0; +#endif if ( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) diff --git a/libavcodec/tableprint.h b/libavcodec/tableprint.h index d81b9a387b..cbe075ec29 100644 --- a/libavcodec/tableprint.h +++ b/libavcodec/tableprint.h @@ -56,8 +56,7 @@ void write_##type##_2d_array(const void *arg, int len, int len2)\ } /** - * \defgroup printfuncs Predefined functions for printing tables - * + * @name Predefined functions for printing tables * \{ */ void write_int8_t_array (const int8_t *, int); diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 41741ff9c5..3125504b7c 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -171,6 +171,13 @@ static int decode_frame(AVCodecContext *avctx, stride = -p->linesize[0]; } + if(avctx->pix_fmt == PIX_FMT_PAL8 && avctx->palctrl){ + memcpy(p->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + if(avctx->palctrl->palette_changed){ + p->palette_has_changed = 1; + avctx->palctrl->palette_changed = 0; + } + } if(colors){ size_t pal_size; if((colors + first_clr) > 256){ diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index f3a044882e..160da8c630 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -35,15 +35,19 @@ typedef struct SeqVideoContext { } SeqVideoContext; -static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size) +static const unsigned char *seq_unpack_rle_block(const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst, int dst_size) { int i, len, sz; GetBitContext gb; int code_table[64]; - /* get the rle codes (at most 64 bytes) */ - init_get_bits(&gb, src, 64 * 8); + /* get the rle codes */ + init_get_bits(&gb, src, (src_end - src) * 8); for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) { + if (get_bits_left(&gb) < 4) + return NULL; code_table[i] = get_sbits(&gb, 4); sz += FFABS(code_table[i]); } @@ -54,8 +58,12 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsig len = code_table[i]; if (len < 0) { len = -len; + if (src_end - src < 1) + return NULL; memset(dst, *src++, FFMIN(len, dst_size)); } else { + if (src_end - src < len) + return NULL; memcpy(dst, src, FFMIN(len, dst_size)); src += len; } @@ -65,25 +73,30 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsig return src; } -static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op1(SeqVideoContext *seq, + const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst) { const unsigned char *color_table; int b, i, len, bits; GetBitContext gb; unsigned char block[8 * 8]; + if (src_end - src < 1) + return NULL; len = *src++; if (len & 0x80) { switch (len & 3) { case 1: - src = seq_unpack_rle_block(src, block, sizeof(block)); + src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (b = 0; b < 8; b++) { memcpy(dst, &block[b * 8], 8); dst += seq->frame.linesize[0]; } break; case 2: - src = seq_unpack_rle_block(src, block, sizeof(block)); + src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (i = 0; i < 8; i++) { for (b = 0; b < 8; b++) dst[b * seq->frame.linesize[0]] = block[i * 8 + b]; @@ -92,9 +105,13 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned break; } } else { + if (len <= 0) + return NULL; + bits = ff_log2_tab[len - 1] + 1; + if (src_end - src < len + 8 * bits) + return NULL; color_table = src; src += len; - bits = ff_log2_tab[len - 1] + 1; init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8; for (b = 0; b < 8; b++) { for (i = 0; i < 8; i++) @@ -106,10 +123,16 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned return src; } -static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op2(SeqVideoContext *seq, + const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst) { int i; + if (src_end - src < 8 * 8) + return NULL; + for (i = 0; i < 8; i++) { memcpy(dst, src, 8); src += 8; @@ -119,11 +142,16 @@ static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned return src; } -static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op3(SeqVideoContext *seq, + const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst) { int pos, offset; do { + if (src_end - src < 2) + return NULL; pos = *src++; offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7); dst[offset] = *src++; @@ -132,8 +160,9 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned return src; } -static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) +static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) { + const unsigned char *data_end = data + data_size; GetBitContext gb; int flags, i, j, x, y, op; unsigned char c[3]; @@ -144,6 +173,8 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int if (flags & 1) { palette = (uint32_t *)seq->frame.data[1]; + if (data_end - data < 256 * 3) + return AVERROR_INVALIDDATA; for (i = 0; i < 256; i++) { for (j = 0; j < 3; j++, data++) c[j] = (*data << 2) | (*data >> 4); @@ -153,6 +184,8 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int } if (flags & 2) { + if (data_end - data < 128) + return AVERROR_INVALIDDATA; init_get_bits(&gb, data, 128 * 8); data += 128; for (y = 0; y < 128; y += 8) for (x = 0; x < 256; x += 8) { @@ -160,17 +193,20 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int op = get_bits(&gb, 2); switch (op) { case 1: - data = seq_decode_op1(seq, data, dst); + data = seq_decode_op1(seq, data, data_end, dst); break; case 2: - data = seq_decode_op2(seq, data, dst); + data = seq_decode_op2(seq, data, data_end, dst); break; case 3: - data = seq_decode_op3(seq, data, dst); + data = seq_decode_op3(seq, data, data_end, dst); break; } + if (!data) + return AVERROR_INVALIDDATA; } } + return 0; } static av_cold int seqvideo_decode_init(AVCodecContext *avctx) @@ -202,7 +238,8 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, return -1; } - seqvideo_decode(seq, buf, buf_size); + if (seqvideo_decode(seq, buf, buf_size)) + return AVERROR_INVALIDDATA; *data_size = sizeof(AVFrame); *(AVFrame *)data = seq->frame; diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index c54eaee346..21588e72f8 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -56,24 +56,24 @@ typedef struct TiffContext { LZWState *lzw; } TiffContext; -static int tget_short(const uint8_t **p, int le){ - int v = le ? AV_RL16(*p) : AV_RB16(*p); +static unsigned tget_short(const uint8_t **p, int le) { + unsigned v = le ? AV_RL16(*p) : AV_RB16(*p); *p += 2; return v; } -static int tget_long(const uint8_t **p, int le){ - int v = le ? AV_RL32(*p) : AV_RB32(*p); +static unsigned tget_long(const uint8_t **p, int le) { + unsigned v = le ? AV_RL32(*p) : AV_RB32(*p); *p += 4; return v; } -static int tget(const uint8_t **p, int type, int le){ +static unsigned tget(const uint8_t **p, int type, int le) { switch(type){ case TIFF_BYTE : return *(*p)++; case TIFF_SHORT: return tget_short(p, le); case TIFF_LONG : return tget_long (p, le); - default : return -1; + default : return UINT_MAX; } } @@ -170,6 +170,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin } switch(s->compr){ case TIFF_RAW: + if (ssrc + size - src < width) + return AVERROR_INVALIDDATA; if (!s->fill_order) { memcpy(dst, src, width); } else { @@ -272,16 +274,23 @@ static int init_image(TiffContext *s) static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) { - int tag, type, count, off, value = 0; + unsigned tag, type, count, off, value = 0; int i, j; uint32_t *pal; const uint8_t *rp, *gp, *bp; + if (end_buf - buf < 12) + return -1; tag = tget_short(&buf, s->le); type = tget_short(&buf, s->le); count = tget_long(&buf, s->le); off = tget_long(&buf, s->le); + if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) { + av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type); + return 0; + } + if(count == 1){ switch(type){ case TIFF_BYTE: @@ -300,13 +309,15 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * break; } default: - value = -1; + value = UINT_MAX; + buf = start + off; + } + } else { + if (count <= 4 && type_sizes[type] * count <= 4) { + buf -= 4; + } else { buf = start + off; } - }else if(type_sizes[type] * count <= 4){ - buf -= 4; - }else{ - buf = start + off; } if(buf && (buf < start || buf > end_buf)){ @@ -336,7 +347,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_SHORT: case TIFF_LONG: s->bpp = 0; - for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le); + for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le); break; default: s->bpp = -1; @@ -349,6 +360,11 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * "Samples per pixel requires a single value, many provided\n"); return AVERROR_INVALIDDATA; } + if (value > 4U) { + av_log(s->avctx, AV_LOG_ERROR, + "Samples per pixel %d is too large\n", value); + return AVERROR_INVALIDDATA; + } if (s->bppcount == 1) s->bpp *= value; s->bppcount = value; @@ -384,8 +400,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * } break; case TIFF_ROWSPERSTRIP: - if(type == TIFF_LONG && value == -1) - value = s->avctx->height; + if (type == TIFF_LONG && value == UINT_MAX) + value = s->height; if(value < 1){ av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n"); return -1; @@ -450,6 +466,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_PAL: pal = (uint32_t *) s->palette; off = type_sizes[type]; + if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3) + return -1; rp = buf; gp = buf + count / 3 * off; bp = buf + count / 3 * off * 2; @@ -480,6 +498,13 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * default: av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n", tag, tag); } + if (s->bpp > 64U) { + av_log(s->avctx, AV_LOG_ERROR, + "This format is not supported (bpp=%d, %d components)\n", + s->bpp, count); + s->bpp = 0; + return AVERROR_INVALIDDATA; + } return 0; } @@ -493,12 +518,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; - int id, le, off, ret; + unsigned off; + int id, le, ret; int i, j, entries; - int stride, soff, ssize; + int stride; + unsigned soff, ssize; uint8_t *dst; //parse image header + if (end_buf - buf < 8) + return AVERROR_INVALIDDATA; id = AV_RL16(buf); buf += 2; if(id == 0x4949) le = 1; else if(id == 0x4D4D) le = 0; @@ -516,11 +545,13 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); return -1; } + // Reset these pointers so we can tell if they were set this frame + s->stripsizes = s->stripdata = NULL; /* parse image file directory */ off = tget_long(&buf, le); - if(orig_buf + off + 14 >= end_buf){ + if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) { av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); - return -1; + return AVERROR_INVALIDDATA; } buf = orig_buf + off; entries = tget_short(&buf, le); @@ -544,23 +575,23 @@ static int decode_frame(AVCodecContext *avctx, stride = p->linesize[0]; dst = p->data[0]; for(i = 0; i < s->height; i += s->rps){ - if(s->stripsizes) + if(s->stripsizes) { + if (s->stripsizes >= end_buf) + return AVERROR_INVALIDDATA; ssize = tget(&s->stripsizes, s->sstype, s->le); - else + } else ssize = s->stripsize; - if (ssize > buf_size) { - av_log(avctx, AV_LOG_ERROR, "Buffer size is smaller than strip size\n"); - return -1; - } - if(s->stripdata){ + if (s->stripdata >= end_buf) + return AVERROR_INVALIDDATA; soff = tget(&s->stripdata, s->sot, s->le); }else soff = s->stripoff; - if (soff < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid stripoff: %d\n", soff); - return AVERROR(EINVAL); + + if (soff > buf_size || ssize > buf_size - soff) { + av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n"); + return -1; } if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) break; diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index f7228f128f..a7a1a40dd1 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -42,6 +42,7 @@ static const uint8_t type_sizes2[6] = { }; typedef struct TiffEncoderContext { + AVClass *avclass; AVCodecContext *avctx; AVFrame picture; @@ -216,6 +217,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, uint8_t *yuv_line = NULL; int shift_h, shift_v; + s->avctx = avctx; s->buf_start = buf; s->buf = &ptr; s->buf_size = buf_size; @@ -303,6 +305,10 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips); strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips); + if (!strip_sizes || !strip_offsets) { + ret = AVERROR(ENOMEM); + goto fail; + } bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp * s->subsampling[0] * s->subsampling[1] + 7) >> 3; @@ -310,6 +316,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, yuv_line = av_malloc(bytes_per_row); if (yuv_line == NULL){ av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n"); + ret = AVERROR(ENOMEM); goto fail; } } @@ -322,6 +329,10 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, zlen = bytes_per_row * s->rps; zbuf = av_malloc(zlen); + if (!zbuf) { + ret = AVERROR(ENOMEM); + goto fail; + } strip_offsets[0] = ptr - buf; zn = 0; for (j = 0; j < s->rps; j++) { @@ -346,8 +357,13 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, } else #endif { - if(s->compr == TIFF_LZW) + if (s->compr == TIFF_LZW) { s->lzws = av_malloc(ff_lzw_encode_state_size); + if (!s->lzws) { + ret = AVERROR(ENOMEM); + goto fail; + } + } for (i = 0; i < s->height; i++) { if (strip_sizes[i / s->rps] == 0) { if(s->compr == TIFF_LZW){ diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index 284dbd8e12..839af44fd5 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -520,6 +520,10 @@ hres,vres,i,i%vres (0 < i < 4) } #define APPLY_C_PREDICTOR() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->c_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -537,6 +541,10 @@ hres,vres,i,i%vres (0 < i < 4) index++; #define APPLY_C_PREDICTOR_24() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->c_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -555,6 +563,10 @@ hres,vres,i,i%vres (0 < i < 4) #define APPLY_Y_PREDICTOR() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->y_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -572,6 +584,10 @@ hres,vres,i,i%vres (0 < i < 4) index++; #define APPLY_Y_PREDICTOR_24() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->y_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 2b9a0cba72..c753a0806e 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -132,7 +132,7 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) huff.val_bits, huff.max_bits); return -1; } - if((huff.nodes < 0) || (huff.nodes > 0x10000)) { + if((huff.nodes <= 0) || (huff.nodes > 0x10000)) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes); return -1; } diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index d903a0119e..b5f74662ba 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -56,6 +56,11 @@ static av_cold int truespeech_decode_init(AVCodecContext * avctx) { // TSContext *c = avctx->priv_data; + if (avctx->channels != 1) { + av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels); + return AVERROR(EINVAL); + } + avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c index bc57ec74cb..b12a608555 100644 --- a/libavcodec/tscc.c +++ b/libavcodec/tscc.c @@ -60,8 +60,6 @@ typedef struct TsccContext { unsigned char* decomp_buf; int height; z_stream zstream; - - uint32_t pal[256]; } CamtasiaContext; /* @@ -110,13 +108,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac /* make the palette available on the way out */ if (c->avctx->pix_fmt == PIX_FMT_PAL8) { - const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - - if (pal) { + memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); + if (c->avctx->palctrl->palette_changed) { c->pic.palette_has_changed = 1; - memcpy(c->pal, pal, AVPALETTE_SIZE); + c->avctx->palctrl->palette_changed = 0; } - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); } *data_size = sizeof(AVFrame); diff --git a/libavcodec/tta.c b/libavcodec/tta.c index dccca46132..ed7665ee29 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -226,7 +226,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) if (avctx->extradata_size < 30) return -1; - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size); + init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8); if (show_bits_long(&s->gb, 32) == AV_RL32("TTA1")) { /* signature */ diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index f8e75bb933..7be13bcf0c 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -822,7 +822,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, const ModeTab *mtab = tctx->mtab; float *out = data; enum FrameType ftype; - int window_type; + int window_type, out_size; static const enum FrameType wtype_to_ftype_table[] = { FT_LONG, FT_LONG, FT_SHORT, FT_LONG, FT_MEDIUM, FT_LONG, FT_LONG, FT_MEDIUM, FT_MEDIUM @@ -835,6 +835,13 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, return buf_size; } + out_size = mtab->size * avctx->channels * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); + return AVERROR(EINVAL); + } + init_get_bits(&gb, buf, buf_size * 8); skip_bits(&gb, get_bits(&gb, 8)); window_type = get_bits(&gb, WINDOW_TYPE_BITS); @@ -857,7 +864,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, return buf_size; } - *data_size = mtab->size*avctx->channels*4; + *data_size = out_size; return buf_size; } diff --git a/libavcodec/txd.c b/libavcodec/txd.c index 0e25458c86..219c337534 100644 --- a/libavcodec/txd.c +++ b/libavcodec/txd.c @@ -23,6 +23,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" +#include "bytestream.h" #include "avcodec.h" #include "s3tc.h" @@ -42,6 +43,7 @@ static av_cold int txd_init(AVCodecContext *avctx) { static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; TXDContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; @@ -52,6 +54,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint32_t *palette = (const uint32_t *)(cur + 88); uint32_t *pal; + if (buf_end - cur < 92) + return AVERROR_INVALIDDATA; version = AV_RL32(cur); d3d_format = AV_RL32(cur+76); w = AV_RL16(cur+80); @@ -69,6 +73,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (depth == 8) { avctx->pix_fmt = PIX_FMT_PAL8; + if (buf_end - cur < 1024) + return AVERROR_INVALIDDATA; cur += 1024; } else if (depth == 16 || depth == 32) avctx->pix_fmt = PIX_FMT_RGB32; @@ -100,6 +106,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, v = AV_RB32(palette+y); pal[y] = (v>>8) + (v<<24); } + if (buf_end - cur < w * h) + return AVERROR_INVALIDDATA; for (y=0; y 1; mipmap_count--) - cur += AV_RL32(cur) + 4; + for (; mipmap_count > 1 && buf_end - cur >= 4; mipmap_count--) { + uint32_t length = bytestream_get_le32(&cur); + if (buf_end - cur < length) + break; + cur += length; + } *picture = s->picture; *data_size = sizeof(AVPicture); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 165ef5bb21..569047fde7 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -32,6 +32,7 @@ #include "libavutil/audioconvert.h" #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" +#include "libavutil/dict.h" #include "avcodec.h" #include "dsputil.h" #include "libavutil/opt.h" @@ -48,7 +49,7 @@ static int volatile entangled_thread_counter=0; static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op); static void *codec_mutex; -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +void *av_fast_realloc(void *ptr, unsigned int *size, FF_INTERNALC_MEM_TYPE min_size) { if(min_size < *size) return ptr; @@ -64,7 +65,7 @@ void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) return ptr; } -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +void av_fast_malloc(void *ptr, unsigned int *size, FF_INTERNALC_MEM_TYPE min_size) { void **p = ptr; if (min_size < *size) @@ -94,6 +95,13 @@ void avcodec_register(AVCodec *codec) codec->next = NULL; } +#if LIBAVCODEC_VERSION_MAJOR < 53 +void register_avcodec(AVCodec *codec) +{ + avcodec_register(codec); +} +#endif + unsigned avcodec_get_edge_width(void) { return EDGE_WIDTH; @@ -142,6 +150,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l case PIX_FMT_YUV420P10BE: case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P10BE: + case PIX_FMT_YUV444P9LE: + case PIX_FMT_YUV444P9BE: + case PIX_FMT_YUV444P10LE: + case PIX_FMT_YUV444P10BE: w_align= 16; //FIXME check for non mpeg style codecs and use less alignment h_align= 16; if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP || s->codec_id == CODEC_ID_H264) @@ -149,8 +161,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l break; case PIX_FMT_YUV411P: case PIX_FMT_UYYVYY411: - w_align=32; - h_align=8; + w_align = 32; + h_align = 16 * 2; break; case PIX_FMT_YUV410P: if(s->codec_id == CODEC_ID_SVQ1){ @@ -165,9 +177,14 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l case PIX_FMT_PAL8: case PIX_FMT_BGR8: case PIX_FMT_RGB8: - if(s->codec_id == CODEC_ID_SMC){ - w_align=4; - h_align=4; + if (s->codec_id == CODEC_ID_SMC || + s->codec_id == CODEC_ID_CINEPAK) { + w_align = 4; + h_align = 4; + } + if (s->codec_id == CODEC_ID_JV) { + w_align = 8; + h_align = 8; } break; case PIX_FMT_BGR24: @@ -176,6 +193,12 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l h_align=4; } break; + case PIX_FMT_RGB24: + if (s->codec_id == CODEC_ID_CINEPAK) { + w_align = 4; + h_align = 4; + } + break; default: w_align= 1; h_align= 1; @@ -219,6 +242,12 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ *width=FFALIGN(*width, align); } +#if LIBAVCODEC_VERSION_MAJOR < 53 +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ + return av_image_check_size(w, h, 0, av_log_ctx); +} +#endif + int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ int i; int w= s->width; @@ -481,9 +510,20 @@ static void avcodec_get_subtitle_defaults(AVSubtitle *sub) sub->pts = AV_NOPTS_VALUE; } +#if FF_API_AVCODEC_OPEN int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) +{ + return avcodec_open2(avctx, codec, NULL); +} +#endif + +int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) { int ret = 0; + AVDictionary *tmp = NULL; + + if (options) + av_dict_copy(&tmp, *options, 0); /* If there is a user-supplied mutex locking routine, call it. */ if (ff_lockmgr_cb) { @@ -510,14 +550,18 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) ret = AVERROR(ENOMEM); goto end; } - if(codec->priv_class){ //this can be droped once all user apps use avcodec_get_context_defaults3() + if (codec->priv_class) { *(AVClass**)avctx->priv_data= codec->priv_class; av_opt_set_defaults(avctx->priv_data); } } + if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp)) < 0) + goto free_and_end; } else { avctx->priv_data = NULL; } + if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) + goto free_and_end; if(avctx->coded_width && avctx->coded_height) avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); @@ -572,6 +616,8 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) if (avctx->codec->encode) { int i; if (avctx->codec->sample_fmts) { + if (avctx->sample_fmt == AV_SAMPLE_FMT_NONE) + avctx->sample_fmt = AV_SAMPLE_FMT_S16; for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) if (avctx->sample_fmt == avctx->codec->sample_fmts[i]) break; @@ -636,8 +682,14 @@ end: if (ff_lockmgr_cb) { (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE); } + if (options) { + av_dict_free(options); + *options = tmp; + } + return ret; free_and_end: + av_dict_free(&tmp); av_freep(&avctx->priv_data); avctx->codec= NULL; goto end; @@ -723,6 +775,22 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, return pts; } +#if FF_API_VIDEO_OLD +int attribute_align_arg avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size) +{ + AVPacket avpkt; + av_init_packet(&avpkt); + avpkt.data = buf; + avpkt.size = buf_size; + // HACK for CorePNG to decode as normal PNG by default + avpkt.flags = AV_PKT_FLAG_KEY; + + return avcodec_decode_video2(avctx, picture, got_picture_ptr, &avpkt); +} +#endif + int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) @@ -734,7 +802,6 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi return -1; if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ - av_packet_split_side_data(avpkt); avctx->pkt = avpkt; if (HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, @@ -773,6 +840,20 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi return ret; } +#if FF_API_AUDIO_OLD +int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size) +{ + AVPacket avpkt; + av_init_packet(&avpkt); + avpkt.data = buf; + avpkt.size = buf_size; + + return avcodec_decode_audio3(avctx, samples, frame_size_ptr, &avpkt); +} +#endif + int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, AVPacket *avpkt) @@ -781,6 +862,11 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa avctx->pkt = avpkt; + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){ @@ -802,6 +888,20 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa return ret; } +#if FF_API_SUBTITLE_OLD +int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size) +{ + AVPacket avpkt; + av_init_packet(&avpkt); + avpkt.data = buf; + avpkt.size = buf_size; + + return avcodec_decode_subtitle2(avctx, sub, got_sub_ptr, &avpkt); +} +#endif + int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) @@ -1133,7 +1233,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx) { if(HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) ff_thread_flush(avctx); - if(avctx->codec->flush) + else if(avctx->codec->flush) avctx->codec->flush(avctx); } @@ -1234,6 +1334,20 @@ unsigned int av_xiphlacing(unsigned char *s, unsigned int v) return n; } +#if LIBAVCODEC_VERSION_MAJOR < 53 +#include "libavutil/parseutils.h" + +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str) +{ + return av_parse_video_size(width_ptr, height_ptr, str); +} + +int av_parse_video_frame_rate(AVRational *frame_rate, const char *arg) +{ + return av_parse_video_rate(frame_rate, arg); +} +#endif + int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b){ int i; for(i=0; ithread_count = thread_count; return ff_thread_init(s); } + +void avcodec_thread_free(AVCodecContext *s) +{ +#if HAVE_THREADS + ff_thread_free(s); +#endif +} + #endif diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 922dc86963..7d8eb606c9 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -281,7 +281,8 @@ static int start_frame(AVCodecContext *avctx, if (!iq_matrix) return -1; memcpy(iq_matrix->ScalingList4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->ScalingList4x4)); - memcpy(iq_matrix->ScalingList8x8, h->pps.scaling_matrix8, sizeof(iq_matrix->ScalingList8x8)); + memcpy(iq_matrix->ScalingList8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->ScalingList8x8[0])); + memcpy(iq_matrix->ScalingList8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->ScalingList8x8[0])); return 0; } diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index d4d76c815f..09bef4a5f9 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -116,6 +116,18 @@ static inline VAMvModeVC1 vc1_get_MVMODE2(VC1Context *v) return 0; } +/** Reconstruct bitstream TTFRM (7.1.1.41, Table-53) */ +static inline int vc1_get_TTFRM(VC1Context *v) +{ + switch (v->ttfrm) { + case TT_8X8: return 0; + case TT_8X4: return 1; + case TT_4X8: return 2; + case TT_4X4: return 3; + } + return 0; +} + /** Pack FFmpeg bitplanes into a VABitPlaneBuffer element */ static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride) { @@ -239,7 +251,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t pic_param->transform_fields.value = 0; /* reset all bits */ pic_param->transform_fields.bits.variable_sized_transform_flag = v->vstransform; pic_param->transform_fields.bits.mb_level_transform_type_flag = v->ttmbf; - pic_param->transform_fields.bits.frame_level_transform_type = v->ttfrm; + pic_param->transform_fields.bits.frame_level_transform_type = vc1_get_TTFRM(v); pic_param->transform_fields.bits.transform_ac_codingset_idx1 = v->c_ac_table_index; pic_param->transform_fields.bits.transform_ac_codingset_idx2 = v->y_ac_table_index; pic_param->transform_fields.bits.intra_transform_dc_table = v->s.dc_table_index; diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index e062a35cc1..90130a0b25 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -40,7 +40,7 @@ /***********************************************************************/ /** - * @defgroup vc1bitplane VC-1 Bitplane decoding + * @name VC-1 Bitplane decoding * @see 8.7, p56 * @{ */ @@ -485,8 +485,8 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) if(ar && ar < 14){ v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar]; }else if(ar == 15){ - w = get_bits(gb, 8); - h = get_bits(gb, 8); + w = get_bits(gb, 8) + 1; + h = get_bits(gb, 8) + 1; v->s.avctx->sample_aspect_ratio = (AVRational){w, h}; } av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den); diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 852c874ee1..157b36cbde 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -137,7 +137,7 @@ static int vc1_init_common(VC1Context *v) /***********************************************************************/ /** - * @defgroup vc1bitplane VC-1 Bitplane decoding + * @name VC-1 Bitplane decoding * @see 8.7, p56 * @{ */ @@ -243,7 +243,7 @@ static void vc1_loop_filter_iblk(VC1Context *v, int pq) } v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8*s->linesize, s->linesize, pq); - if (s->mb_y == s->mb_height-1) { + if (s->mb_y == s->end_mb_y-1) { if (s->mb_x) { v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq); v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq); @@ -295,7 +295,7 @@ static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq) v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize, s->linesize, pq); } - if (s->mb_y == s->mb_height) { + if (s->mb_y == s->end_mb_y) { if (s->mb_x) { if (s->mb_x >= 2) v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq); @@ -774,7 +774,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v) /***********************************************************************/ /** - * @defgroup vc1block VC-1 Block-level functions + * @name VC-1 Block-level functions * @see 7.1.4, p91 and 8.1.1.7, p(1)04 * @{ */ @@ -1512,7 +1512,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, /** @} */ // Block group /** - * @defgroup vc1_std_mb VC1 Macroblock-level functions in Simple/Main Profiles + * @name VC1 Macroblock-level functions in Simple/Main Profiles * @see 7.1.4, p91 and 8.1.1.7, p(1)04 * @{ */ @@ -2330,7 +2330,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_ } else { dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize; } - if (s->mb_y != s->mb_height || block_num < 2) { + if (s->mb_y != s->end_mb_y || block_num < 2) { int16_t (*mv)[2]; int mv_stride; @@ -3020,7 +3020,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->mb_x = 0; ff_init_block_index(s); memset(&s->coded_block[s->block_index[0]-s->b8_stride], 0, - s->b8_stride * sizeof(*s->coded_block)); + (1 + s->b8_stride) * sizeof(*s->coded_block)); } for(; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; @@ -3096,7 +3096,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) if(v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq); } if (v->s.loop_filter) - ff_draw_horiz_band(s, (s->mb_height-1)*16, 16); + ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16); ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END)); } @@ -3219,7 +3219,7 @@ static void vc1_decode_b_blocks(VC1Context *v) s->first_slice_line = 0; } if (v->s.loop_filter) - ff_draw_horiz_band(s, (s->mb_height-1)*16, 16); + ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16); ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END)); } @@ -3227,9 +3227,9 @@ static void vc1_decode_skip_blocks(VC1Context *v) { MpegEncContext *s = &v->s; - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END)); s->first_slice_line = 1; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { + for(s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; ff_init_block_index(s); ff_update_block_index(s); @@ -3716,11 +3716,21 @@ static int vc1_decode_frame(AVCodecContext *avctx, if(s->last_picture_ptr==NULL && (s->pict_type==AV_PICTURE_TYPE_B || s->dropable)){ goto err; } +#if FF_API_HURRY_UP + /* skip b frames if we are in a hurry */ + if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return -1;//buf_size; +#endif if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) { goto end; } +#if FF_API_HURRY_UP + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) { + goto err; + } +#endif if(s->next_p_frame_damaged){ if(s->pict_type==AV_PICTURE_TYPE_B) @@ -3840,9 +3850,11 @@ AVCodec ff_vc1_decoder = { vc1_decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DELAY, NULL, + .flush = ff_mpeg_flush, .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), .pix_fmts = ff_hwaccel_pixfmt_list_420, - .profiles = NULL_IF_CONFIG_SMALL(profiles) + .profiles = NULL_IF_CONFIG_SMALL(profiles), + .flush = ff_mpeg_flush, }; #if CONFIG_WMV3_DECODER @@ -3857,9 +3869,11 @@ AVCodec ff_wmv3_decoder = { vc1_decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DELAY, NULL, + .flush = ff_mpeg_flush, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), .pix_fmts = ff_hwaccel_pixfmt_list_420, - .profiles = NULL_IF_CONFIG_SMALL(profiles) + .profiles = NULL_IF_CONFIG_SMALL(profiles), + .flush = ff_mpeg_flush, }; #endif diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index 19bd96bc15..9dc2745922 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -183,7 +183,8 @@ void ff_vdpau_h264_picture_complete(MpegEncContext *s) render->info.h264.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; render->info.h264.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present; memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4)); - memcpy(render->info.h264.scaling_lists_8x8, h->pps.scaling_matrix8, sizeof(render->info.h264.scaling_lists_8x8)); + memcpy(render->info.h264.scaling_lists_8x8[0], h->pps.scaling_matrix8[0], sizeof(render->info.h264.scaling_lists_8x8[0])); + memcpy(render->info.h264.scaling_lists_8x8[1], h->pps.scaling_matrix8[3], sizeof(render->info.h264.scaling_lists_8x8[0])); ff_draw_horiz_band(s, 0, s->avctx->height); render->bitstream_buffers_used = 0; diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h index 0dc6fb850b..ab5f682c62 100644 --- a/libavcodec/vdpau.h +++ b/libavcodec/vdpau.h @@ -67,13 +67,6 @@ struct vdpau_render_state { int state; ///< Holds FF_VDPAU_STATE_* values. - /** Describe size/location of the compressed video data. - Set to 0 when freeing bitstream_buffers. */ - int bitstream_buffers_allocated; - int bitstream_buffers_used; - /** The user is responsible for freeing this buffer using av_freep(). */ - VdpBitstreamBuffer *bitstream_buffers; - /** picture parameter information for all supported codecs */ union VdpPictureInfo { VdpPictureInfoH264 h264; @@ -81,6 +74,13 @@ struct vdpau_render_state { VdpPictureInfoVC1 vc1; VdpPictureInfoMPEG4Part2 mpeg4; } info; + + /** Describe size/location of the compressed video data. + Set to 0 when freeing bitstream_buffers. */ + int bitstream_buffers_allocated; + int bitstream_buffers_used; + /** The user is responsible for freeing this buffer using av_freep(). */ + VdpBitstreamBuffer *bitstream_buffers; }; /* @}*/ diff --git a/libavcodec/version.h b/libavcodec/version.h index 100c06dfe6..0cc3410f4b 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -20,8 +20,8 @@ #ifndef AVCODEC_VERSION_H #define AVCODEC_VERSION_H -#define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 7 +#define LIBAVCODEC_VERSION_MAJOR 52 +#define LIBAVCODEC_VERSION_MINOR 123 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -41,12 +41,45 @@ #ifndef FF_API_PALETTE_CONTROL #define FF_API_PALETTE_CONTROL (LIBAVCODEC_VERSION_MAJOR < 54) #endif +#ifndef FF_API_MM_FLAGS +#define FF_API_MM_FLAGS (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_OPT_SHOW +#define FF_API_OPT_SHOW (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_AUDIO_OLD +#define FF_API_AUDIO_OLD (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_VIDEO_OLD +#define FF_API_VIDEO_OLD (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_SUBTITLE_OLD +#define FF_API_SUBTITLE_OLD (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_USE_LPC +#define FF_API_USE_LPC (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_SET_STRING_OLD +#define FF_API_SET_STRING_OLD (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_INOFFICIAL +#define FF_API_INOFFICIAL (LIBAVCODEC_VERSION_MAJOR < 53) +#endif #ifndef FF_API_OLD_SAMPLE_FMT #define FF_API_OLD_SAMPLE_FMT (LIBAVCODEC_VERSION_MAJOR < 54) #endif #ifndef FF_API_OLD_AUDIOCONVERT #define FF_API_OLD_AUDIOCONVERT (LIBAVCODEC_VERSION_MAJOR < 54) #endif +#ifndef FF_API_HURRY_UP +#define FF_API_HURRY_UP (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_RATE_EMU +#define FF_API_RATE_EMU (LIBAVCODEC_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_MB_Q +#define FF_API_MB_Q (LIBAVCODEC_VERSION_MAJOR < 53) +#endif #ifndef FF_API_ANTIALIAS_ALGO #define FF_API_ANTIALIAS_ALGO (LIBAVCODEC_VERSION_MAJOR < 54) #endif @@ -68,5 +101,8 @@ #ifndef FF_API_GET_PIX_FMT_NAME #define FF_API_GET_PIX_FMT_NAME (LIBAVCODEC_VERSION_MAJOR < 54) #endif +#ifndef FF_API_AVCODEC_OPEN +#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 54) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index b9acfe921c..94ae895057 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -72,9 +72,11 @@ typedef struct VmdVideoContext { #define QUEUE_SIZE 0x1000 #define QUEUE_MASK 0x0FFF -static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len) +static void lz_unpack(const unsigned char *src, int src_len, + unsigned char *dest, int dest_len) { const unsigned char *s; + const unsigned char *s_end; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -87,8 +89,12 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le unsigned int i, j; s = src; + s_end = src + src_len; d = dest; d_end = d + dest_len; + + if (s_end - s < 8) + return; dataleft = AV_RL32(s); s += 4; memset(queue, 0x20, QUEUE_SIZE); @@ -101,10 +107,10 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le speclen = 100; /* no speclen */ } - while (dataleft > 0) { + while (s_end - s > 0 && dataleft > 0) { tag = *s++; if ((tag == 0xFF) && (dataleft > 8)) { - if (d + 8 > d_end) + if (d_end - d < 8 || s_end - s < 8) return; for (i = 0; i < 8; i++) { queue[qpos++] = *d++ = *s++; @@ -116,18 +122,23 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le if (dataleft == 0) break; if (tag & 0x01) { - if (d + 1 > d_end) + if (d_end - d < 1 || s_end - s < 1) return; queue[qpos++] = *d++ = *s++; qpos &= QUEUE_MASK; dataleft--; } else { + if (s_end - s < 2) + return; chainofs = *s++; chainofs |= ((*s & 0xF0) << 4); chainlen = (*s++ & 0x0F) + 3; - if (chainlen == speclen) + if (chainlen == speclen) { + if (s_end - s < 1) + return; chainlen = *s++ + 0xF + 3; - if (d + chainlen > d_end) + } + if (d_end - d < chainlen) return; for (j = 0; j < chainlen; j++) { *d = queue[chainofs++ & QUEUE_MASK]; @@ -142,32 +153,39 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le } } -static int rle_unpack(const unsigned char *src, unsigned char *dest, - int src_len, int dest_len) +static int rle_unpack(const unsigned char *src, int src_len, int src_count, + unsigned char *dest, int dest_len) { const unsigned char *ps; + const unsigned char *ps_end; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; ps = src; + ps_end = src + src_len; pd = dest; - if (src_len & 1) + if (src_count & 1) { + if (ps_end - ps < 1) + return 0; *pd++ = *ps++; + } - src_len >>= 1; + src_count >>= 1; i = 0; do { + if (ps_end - ps < 1) + break; l = *ps++; if (l & 0x80) { l = (l & 0x7F) * 2; - if (pd + l > dest_end) + if (dest_end - pd < l || ps_end - ps < l) return ps - src; memcpy(pd, ps, l); ps += l; pd += l; } else { - if (pd + i > dest_end) + if (dest_end - pd < i || ps_end - ps < 2) return ps - src; for (i = 0; i < l; i++) { *pd++ = ps[0]; @@ -176,7 +194,7 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest, ps += 2; } i += l; - } while (i < src_len); + } while (i < src_count); return ps - src; } @@ -189,8 +207,10 @@ static void vmd_decode(VmdVideoContext *s) /* point to the start of the encoded data */ const unsigned char *p = s->buf + 16; + const unsigned char *p_end = s->buf + s->size; 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 */ @@ -204,6 +224,16 @@ static void vmd_decode(VmdVideoContext *s) frame_y = AV_RL16(&s->buf[8]); frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; + 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; + 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; if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && (frame_x || frame_y)) { @@ -216,8 +246,9 @@ static void vmd_decode(VmdVideoContext *s) /* if only a certain region will be updated, copy the entire previous * frame before the decode */ - if (frame_x || frame_y || (frame_width != s->avctx->width) || - (frame_height != s->avctx->height)) { + if (s->prev_frame.data[0] && + (frame_x || frame_y || (frame_width != s->avctx->width) || + (frame_height != s->avctx->height))) { memcpy(s->frame.data[0], s->prev_frame.data[0], s->avctx->height * s->frame.linesize[0]); @@ -225,6 +256,8 @@ static void vmd_decode(VmdVideoContext *s) /* check if there is a new palette */ if (s->buf[15] & 0x02) { + if (p_end - p < 2 + 3 * PALETTE_COUNT) + return; p += 2; palette32 = (unsigned int *)s->palette; for (i = 0; i < PALETTE_COUNT; i++) { @@ -233,16 +266,17 @@ static void vmd_decode(VmdVideoContext *s) b = *p++ * 4; palette32[i] = (r << 16) | (g << 8) | (b); } - s->size -= (256 * 3 + 2); } - if (s->size >= 0) { + if (p < p_end) { /* originally UnpackFrame in VAG's code */ pb = p; + pb_end = p_end; meth = *pb++; if (meth & 0x80) { - lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); + 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]; @@ -252,17 +286,19 @@ static void vmd_decode(VmdVideoContext *s) 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) + 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) + if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) return; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -280,6 +316,8 @@ static void vmd_decode(VmdVideoContext *s) case 2: for (i = 0; i < frame_height; i++) { + if (pb_end -pb < frame_width) + return; memcpy(dp, pb, frame_width); pb += frame_width; dp += s->frame.linesize[0]; @@ -291,18 +329,25 @@ static void vmd_decode(VmdVideoContext *s) 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, &dp[ofs], len, frame_width - ofs); - else + len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs); + else { + 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) + if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) return; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -523,7 +568,10 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, silent_chunks = 0; if (block_type == BLOCK_TYPE_INITIAL) { - uint32_t flags = AV_RB32(buf); + uint32_t flags; + if (buf_size < 4) + return -1; + flags = AV_RB32(buf); silent_chunks = av_popcount(flags); buf += 4; buf_size -= 4; diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index 6455d86f77..50f5f51501 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -484,6 +484,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp); + return AVERROR_INVALIDDATA; } return 0; diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c index fc830293cc..efa6404f2a 100644 --- a/libavcodec/vorbis.c +++ b/libavcodec/vorbis.c @@ -117,7 +117,8 @@ int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num) return 0; } -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) +int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext, + vorbis_floor1_entry *list, int values) { int i; list[0].sort = 0; @@ -141,6 +142,11 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) for (i = 0; i < values - 1; i++) { int j; for (j = i + 1; j < values; j++) { + if (list[i].x == list[j].x) { + av_log(avccontext, AV_LOG_ERROR, + "Duplicate value found in floor 1 X coordinates\n"); + return AVERROR_INVALIDDATA; + } if (list[list[i].sort].x > list[list[j].sort].x) { int tmp = list[i].sort; list[i].sort = list[j].sort; @@ -148,9 +154,10 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) } } } + return 0; } -static inline void render_line_unrolled(intptr_t x, intptr_t y, int x1, +static inline void render_line_unrolled(intptr_t x, int y, int x1, intptr_t sy, int ady, int adx, float *buf) { @@ -162,14 +169,14 @@ static inline void render_line_unrolled(intptr_t x, intptr_t y, int x1, if (err >= 0) { err += ady - adx; y += sy; - buf[x++] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } if (x <= 0) { if (err + ady >= 0) y += sy; - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } } @@ -179,14 +186,14 @@ static void render_line(int x0, int y0, int x1, int y1, float *buf) int adx = x1 - x0; int ady = FFABS(dy); int sy = dy < 0 ? -1 : 1; - buf[x0] = ff_vorbis_floor1_inverse_db_table[y0]; + buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)]; if (ady*2 <= adx) { // optimized common case render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); } else { - int base = dy / adx; - int x = x0; - int y = y0; - int err = -adx; + int base = dy / adx; + int x = x0; + int y = y0; + int err = -adx; ady -= FFABS(base) * adx; while (++x < x1) { y += base; @@ -195,7 +202,7 @@ static void render_line(int x0, int y0, int x1, int y1, float *buf) err -= adx; y += sy; } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } } } diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h index 15b5d85b36..51a1f216d7 100644 --- a/libavcodec/vorbis.h +++ b/libavcodec/vorbis.h @@ -36,7 +36,8 @@ typedef struct { uint16_t high; } vorbis_floor1_entry; -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values); +int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext, + vorbis_floor1_entry *list, int values); unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n) int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num); void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 024c8fd3cf..a266cdbc40 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -559,7 +559,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) } // Precalculate order of x coordinates - needed for decode - ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim); + if (ff_vorbis_ready_floor1_list(vc->avccontext, + floor_setup->data.t1.list, + floor_setup->data.t1.x_list_dim)) { + return AVERROR_INVALIDDATA; + } } else if (floor_setup->floor_type == 0) { unsigned max_codebook_dim = 0; @@ -568,6 +572,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) floor_setup->data.t0.order = get_bits(gb, 8); floor_setup->data.t0.rate = get_bits(gb, 16); floor_setup->data.t0.bark_map_size = get_bits(gb, 16); + if (floor_setup->data.t0.bark_map_size == 0) { + av_log(vc->avccontext, AV_LOG_ERROR, + "Floor 0 bark map size is 0.\n"); + return AVERROR_INVALIDDATA; + } floor_setup->data.t0.amplitude_bits = get_bits(gb, 6); /* zero would result in a div by zero later * * 2^0 - 1 == 0 */ @@ -660,7 +669,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) res_setup->partition_size = get_bits(gb, 24) + 1; /* Validations to prevent a buffer overflow later. */ if (res_setup->begin>res_setup->end || - res_setup->end > vc->avccontext->channels * vc->blocksize[1] / 2 || + res_setup->end > (res_setup->type == 2 ? vc->avccontext->channels : 1) * vc->blocksize[1] / 2 || (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) { av_log(vc->avccontext, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n", @@ -1232,20 +1241,20 @@ static int vorbis_floor1_decode(vorbis_context *vc, floor1_flag[i] = 1; if (val >= room) { if (highroom > lowroom) { - floor1_Y_final[i] = val - lowroom + predicted; + floor1_Y_final[i] = av_clip_uint16(val - lowroom + predicted); } else { - floor1_Y_final[i] = predicted - val + highroom - 1; + floor1_Y_final[i] = av_clip_uint16(predicted - val + highroom - 1); } } else { if (val & 1) { - floor1_Y_final[i] = predicted - (val + 1) / 2; + floor1_Y_final[i] = av_clip_uint16(predicted - (val + 1) / 2); } else { - floor1_Y_final[i] = predicted + val / 2; + floor1_Y_final[i] = av_clip_uint16(predicted + val / 2); } } } else { floor1_flag[i] = 0; - floor1_Y_final[i] = predicted; + floor1_Y_final[i] = av_clip_uint16(predicted); } av_dlog(NULL, " Decoded floor(%d) = %u / val %u\n", @@ -1269,6 +1278,7 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, uint8_t *do_not_decode, float *vec, unsigned vlen, + unsigned ch_left, int vr_type) { GetBitContext *gb = &vc->gb; @@ -1276,6 +1286,7 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, unsigned ptns_to_read = vr->ptns_to_read; uint8_t *classifs = vr->classifs; unsigned pass, ch_used, i, j, k, l; + unsigned max_output = (ch - 1) * vlen; if (vr_type == 2) { for (j = 1; j < ch; ++j) @@ -1283,8 +1294,15 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, if (do_not_decode[0]) return 0; ch_used = 1; + max_output += vr->end / ch; } else { ch_used = ch; + max_output += vr->end; + } + + if (max_output > ch_left * vlen) { + av_log(vc->avccontext, AV_LOG_ERROR, "Insufficient output buffer\n"); + return -1; } av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); @@ -1411,14 +1429,15 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, unsigned ch, uint8_t *do_not_decode, - float *vec, unsigned vlen) + float *vec, unsigned vlen, + unsigned ch_left) { if (vr->type == 2) - return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 2); + return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 2); else if (vr->type == 1) - return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 1); + return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 1); else if (vr->type == 0) - return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 0); + return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 0); else { av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); return -1; @@ -1466,6 +1485,8 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) uint8_t res_chan[255]; unsigned res_num = 0; int retlen = 0; + unsigned ch_left = vc->audio_channels; + unsigned vlen; if (get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); @@ -1485,11 +1506,12 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) blockflag = vc->modes[mode_number].blockflag; blocksize = vc->blocksize[blockflag]; + vlen = blocksize / 2; if (blockflag) skip_bits(gb, 2); // previous_window, next_window - memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ? - memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ? + memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ? + memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ? // Decode floor @@ -1509,7 +1531,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) return -1; } no_residue[i] = ret; - ch_floor_ptr += blocksize / 2; + ch_floor_ptr += vlen; } // Nonzero vector propagate @@ -1526,6 +1548,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) for (i = 0; i < mapping->submaps; ++i) { vorbis_residue *residue; unsigned ch = 0; + int ret; for (j = 0; j < vc->audio_channels; ++j) { if ((mapping->submaps == 1) || (i == mapping->mux[j])) { @@ -1540,9 +1563,18 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) } } residue = &vc->residues[mapping->submap_residue[i]]; - vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2); + if (ch_left < ch) { + av_log(vc->avccontext, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n"); + return -1; + } + if (ch) { + ret = vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, vlen, ch_left); + if (ret < 0) + return ret; + } - ch_res_ptr += ch * blocksize / 2; + ch_res_ptr += ch * vlen; + ch_left -= ch; } // Inverse coupling @@ -1605,7 +1637,7 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, vorbis_context *vc = avccontext->priv_data ; GetBitContext *gb = &(vc->gb); const float *channel_ptrs[255]; - int i, len; + int i, len, out_size; if (!buf_size) return 0; @@ -1630,6 +1662,13 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb) / 8, get_bits_count(gb) % 8, len); + out_size = len * vc->audio_channels * + av_get_bytes_per_sample(avccontext->sample_fmt); + if (*data_size < out_size) { + av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n"); + return AVERROR(EINVAL); + } + if (vc->audio_channels > 8) { for (i = 0; i < vc->audio_channels; i++) channel_ptrs[i] = vc->channel_floors + i * len; @@ -1645,8 +1684,7 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len, vc->audio_channels); - *data_size = len * vc->audio_channels * - av_get_bytes_per_sample(avccontext->sample_fmt); + *data_size = out_size; return buf_size ; } diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index 617e2b7cc4..3f8a283786 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -155,7 +155,7 @@ static int cb_lookup_vals(int lookup, int dimentions, int entries) return 0; } -static void ready_codebook(vorbis_enc_codebook *cb) +static int ready_codebook(vorbis_enc_codebook *cb) { int i; @@ -167,6 +167,8 @@ static void ready_codebook(vorbis_enc_codebook *cb) int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions); cb->pow2 = av_mallocz(sizeof(float) * cb->nentries); + if (!cb->dimentions || !cb->pow2) + return AVERROR(ENOMEM); for (i = 0; i < cb->nentries; i++) { float last = 0; int j; @@ -187,13 +189,16 @@ static void ready_codebook(vorbis_enc_codebook *cb) cb->pow2[i] /= 2.; } } + return 0; } -static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) +static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) { int i; assert(rc->type == 2); rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications); + if (!rc->maxes) + return AVERROR(ENOMEM); for (i = 0; i < rc->classifications; i++) { int j; vorbis_enc_codebook * cb; @@ -223,15 +228,16 @@ static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) rc->maxes[i][0] += 0.8; rc->maxes[i][1] += 0.8; } + return 0; } -static void create_vorbis_context(vorbis_enc_context *venc, - AVCodecContext *avccontext) +static int create_vorbis_context(vorbis_enc_context *venc, + AVCodecContext *avccontext) { vorbis_enc_floor *fc; vorbis_enc_residue *rc; vorbis_enc_mapping *mc; - int i, book; + int i, book, ret; venc->channels = avccontext->channels; venc->sample_rate = avccontext->sample_rate; @@ -239,6 +245,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->ncodebooks = FF_ARRAY_ELEMS(cvectors); venc->codebooks = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks); + if (!venc->codebooks) + return AVERROR(ENOMEM); // codebook 0..14 - floor1 book, values 0..255 // codebook 15 residue masterbook @@ -255,27 +263,36 @@ static void create_vorbis_context(vorbis_enc_context *venc, cb->lens = av_malloc(sizeof(uint8_t) * cb->nentries); cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries); + if (!cb->lens || !cb->codewords) + return AVERROR(ENOMEM); memcpy(cb->lens, cvectors[book].clens, cvectors[book].len); memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); if (cb->lookup) { vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); cb->quantlist = av_malloc(sizeof(int) * vals); + if (!cb->quantlist) + return AVERROR(ENOMEM); for (i = 0; i < vals; i++) cb->quantlist[i] = cvectors[book].quant[i]; } else { cb->quantlist = NULL; } - ready_codebook(cb); + if ((ret = ready_codebook(cb)) < 0) + return ret; } venc->nfloors = 1; venc->floors = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors); + if (!venc->floors) + return AVERROR(ENOMEM); // just 1 floor fc = &venc->floors[0]; fc->partitions = NUM_FLOOR_PARTITIONS; fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions); + if (!fc->partition_to_class) + return AVERROR(ENOMEM); fc->nclasses = 0; for (i = 0; i < fc->partitions; i++) { static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4}; @@ -284,6 +301,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, } fc->nclasses++; fc->classes = av_malloc(sizeof(vorbis_enc_floor_class) * fc->nclasses); + if (!fc->classes) + return AVERROR(ENOMEM); for (i = 0; i < fc->nclasses; i++) { vorbis_enc_floor_class * c = &fc->classes[i]; int j, books; @@ -292,6 +311,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, c->masterbook = floor_classes[i].masterbook; books = (1 << c->subclass); c->books = av_malloc(sizeof(int) * books); + if (!c->books) + return AVERROR(ENOMEM); for (j = 0; j < books; j++) c->books[j] = floor_classes[i].nbooks[j]; } @@ -303,6 +324,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, fc->values += fc->classes[fc->partition_to_class[i]].dim; fc->list = av_malloc(sizeof(vorbis_floor1_entry) * fc->values); + if (!fc->list) + return AVERROR(ENOMEM); fc->list[0].x = 0; fc->list[1].x = 1 << fc->rangebits; for (i = 2; i < fc->values; i++) { @@ -313,10 +336,13 @@ static void create_vorbis_context(vorbis_enc_context *venc, }; fc->list[i].x = a[i - 2]; } - ff_vorbis_ready_floor1_list(fc->list, fc->values); + if (ff_vorbis_ready_floor1_list(avccontext, fc->list, fc->values)) + return AVERROR(EINVAL); venc->nresidues = 1; venc->residues = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues); + if (!venc->residues) + return AVERROR(ENOMEM); // single residue rc = &venc->residues[0]; @@ -327,6 +353,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, rc->classifications = 10; rc->classbook = 15; rc->books = av_malloc(sizeof(*rc->books) * rc->classifications); + if (!rc->books) + return AVERROR(ENOMEM); { static const int8_t a[10][8] = { { -1, -1, -1, -1, -1, -1, -1, -1, }, @@ -342,19 +370,26 @@ static void create_vorbis_context(vorbis_enc_context *venc, }; memcpy(rc->books, a, sizeof a); } - ready_residue(rc, venc); + if ((ret = ready_residue(rc, venc)) < 0) + return ret; venc->nmappings = 1; venc->mappings = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings); + if (!venc->mappings) + return AVERROR(ENOMEM); // single mapping mc = &venc->mappings[0]; mc->submaps = 1; mc->mux = av_malloc(sizeof(int) * venc->channels); + if (!mc->mux) + return AVERROR(ENOMEM); for (i = 0; i < venc->channels; i++) mc->mux[i] = 0; mc->floor = av_malloc(sizeof(int) * mc->submaps); mc->residue = av_malloc(sizeof(int) * mc->submaps); + if (!mc->floor || !mc->residue) + return AVERROR(ENOMEM); for (i = 0; i < mc->submaps; i++) { mc->floor[i] = 0; mc->residue[i] = 0; @@ -362,6 +397,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, mc->coupling_steps = venc->channels == 2 ? 1 : 0; mc->magnitude = av_malloc(sizeof(int) * mc->coupling_steps); mc->angle = av_malloc(sizeof(int) * mc->coupling_steps); + if (!mc->magnitude || !mc->angle) + return AVERROR(ENOMEM); if (mc->coupling_steps) { mc->magnitude[0] = 0; mc->angle[0] = 1; @@ -369,6 +406,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->nmodes = 1; venc->modes = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes); + if (!venc->modes) + return AVERROR(ENOMEM); // single mode venc->modes[0].blockflag = 0; @@ -379,12 +418,18 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1])); venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); venc->coeffs = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); + if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs) + return AVERROR(ENOMEM); venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6]; venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6]; - ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0); - ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0); + if ((ret = ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0)) < 0) + return ret; + if ((ret = ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0)) < 0) + return ret; + + return 0; } static void put_float(PutBitContext *pb, float f) @@ -647,6 +692,8 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) len = hlens[0] + hlens[1] + hlens[2]; p = *out = av_mallocz(64 + len + len/255); + if (!p) + return AVERROR(ENOMEM); *p++ = 2; p += av_xiphlacing(p, hlens[0]); @@ -952,33 +999,6 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a return 1; } -static av_cold int vorbis_encode_init(AVCodecContext *avccontext) -{ - vorbis_enc_context *venc = avccontext->priv_data; - - if (avccontext->channels != 2) { - av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n"); - return -1; - } - - create_vorbis_context(venc, avccontext); - - if (avccontext->flags & CODEC_FLAG_QSCALE) - venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; - else - venc->quality = 0.03; - venc->quality *= venc->quality; - - avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata); - - avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); - - avccontext->coded_frame = avcodec_alloc_frame(); - avccontext->coded_frame->key_frame = 1; - - return 0; -} - static int vorbis_encode_frame(AVCodecContext *avccontext, unsigned char *packets, int buf_size, void *data) @@ -1102,6 +1122,43 @@ static av_cold int vorbis_encode_close(AVCodecContext *avccontext) return 0 ; } +static av_cold int vorbis_encode_init(AVCodecContext *avccontext) +{ + vorbis_enc_context *venc = avccontext->priv_data; + int ret; + + if (avccontext->channels != 2) { + av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n"); + return -1; + } + + if ((ret = create_vorbis_context(venc, avccontext)) < 0) + goto error; + + if (avccontext->flags & CODEC_FLAG_QSCALE) + venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; + else + venc->quality = 0.03; + venc->quality *= venc->quality; + + if ((ret = put_main_header(venc, (uint8_t**)&avccontext->extradata)) < 0) + goto error; + avccontext->extradata_size = ret; + + avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); + + avccontext->coded_frame = avcodec_alloc_frame(); + if (!avccontext->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } + + return 0; +error: + vorbis_encode_close(avccontext); + return ret; +} + AVCodec ff_vorbis_encoder = { "vorbis", AVMEDIA_TYPE_AUDIO, diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 148f1179e3..648c464aed 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -45,6 +45,7 @@ #define FRAGMENT_PIXELS 8 static av_cold int vp3_decode_end(AVCodecContext *avctx); +static void vp3_decode_flush(AVCodecContext *avctx); //FIXME split things out into their own arrays typedef struct Vp3Fragment { @@ -890,7 +891,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, /* decode a VLC into a token */ token = get_vlc2(gb, vlc_table, 11, 3); /* use the token to get a zero run, a coefficient, and an eob run */ - if (token <= 6) { + if ((unsigned) token <= 6U) { eob_run = eob_run_base[token]; if (eob_run_get_bits[token]) eob_run += get_bits(gb, eob_run_get_bits[token]); @@ -908,7 +909,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, coeff_i += eob_run; eob_run = 0; } - } else { + } else if (token >= 0) { bits_to_get = coeff_get_bits[token]; if (bits_to_get) bits_to_get = get_bits(gb, bits_to_get); @@ -942,6 +943,10 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, for (i = coeff_index+1; i <= coeff_index+zero_run; i++) s->num_coded_frags[plane][i]--; coeff_i++; + } else { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid token %d\n", token); + return -1; } } @@ -991,6 +996,8 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* unpack the Y plane DC coefficients */ residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, 0, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; /* reverse prediction of the Y-plane DC coefficients */ reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]); @@ -998,8 +1005,12 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* unpack the C plane DC coefficients */ residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, 1, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, 2, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; /* reverse prediction of the C-plane DC coefficients */ if (!(s->avctx->flags & CODEC_FLAG_GRAY)) @@ -1036,11 +1047,17 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) for (i = 1; i <= 63; i++) { residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i, 0, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, 1, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, 2, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; } return 0; @@ -1291,6 +1308,10 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag, case 1: // zero run s->dct_tokens[plane][i]++; i += (token >> 2) & 0x7f; + if(i>63){ + av_log(s->avctx, AV_LOG_ERROR, "Coefficient index overflow\n"); + return -1; + } block[perm[i]] = (token >> 9) * dequantizer[perm[i]]; i++; break; @@ -1302,6 +1323,8 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag, return i; } } while (i < 64); + // return value is expected to be a valid level + i--; end: // the actual DC+prediction is in the fragment structure block[0] = frag->dc * s->qmat[0][inter][plane][0]; @@ -1777,10 +1800,15 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * Vp3DecodeContext *s = dst->priv_data, *s1 = src->priv_data; int qps_changed = 0, i, err; +#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) + if (!s1->current_frame.data[0] ||s->width != s1->width - ||s->height!= s1->height) + ||s->height!= s1->height) { + if (s != s1) + copy_fields(s, s1, golden_frame, current_frame); return -1; + } if (s != s1) { // init tables if the first frame hasn't been decoded @@ -1796,8 +1824,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * memcpy(s->motion_val[1], s1->motion_val[1], c_fragment_count * sizeof(*s->motion_val[1])); } -#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) - // copy previous frame data copy_fields(s, s1, golden_frame, dsp); @@ -1987,9 +2013,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) Vp3DecodeContext *s = avctx->priv_data; int i; - if (avctx->is_copy && !s->current_frame.data[0]) - return 0; - av_free(s->superblock_coding); av_free(s->all_fragments); av_free(s->coded_fragment_list[0]); @@ -2016,12 +2039,7 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) free_vlc(&s->motion_vector_vlc); /* release all frames */ - if (s->golden_frame.data[0]) - ff_thread_release_buffer(avctx, &s->golden_frame); - if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY) - ff_thread_release_buffer(avctx, &s->last_frame); - /* no need to release the current_frame since it will always be pointing - * to the same frame as either the golden or last frame */ + vp3_decode_flush(avctx); return 0; } @@ -2321,6 +2339,43 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) return vp3_decode_init(avctx); } +static void vp3_decode_flush(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + + if (s->golden_frame.data[0]) { + if (s->golden_frame.data[0] == s->last_frame.data[0]) + memset(&s->last_frame, 0, sizeof(AVFrame)); + if (s->current_frame.data[0] == s->golden_frame.data[0]) + memset(&s->current_frame, 0, sizeof(AVFrame)); + ff_thread_release_buffer(avctx, &s->golden_frame); + } + if (s->last_frame.data[0]) { + if (s->current_frame.data[0] == s->last_frame.data[0]) + memset(&s->current_frame, 0, sizeof(AVFrame)); + ff_thread_release_buffer(avctx, &s->last_frame); + } + if (s->current_frame.data[0]) + ff_thread_release_buffer(avctx, &s->current_frame); +} + +static int vp3_init_thread_copy(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + + s->superblock_coding = NULL; + s->all_fragments = NULL; + s->coded_fragment_list[0] = NULL; + s->dct_tokens_base = NULL; + s->superblock_fragments = NULL; + s->macroblock_coding = NULL; + s->motion_val[0] = NULL; + s->motion_val[1] = NULL; + s->edge_emu_buffer = NULL; + + return 0; +} + AVCodec ff_theora_decoder = { "theora", AVMEDIA_TYPE_VIDEO, @@ -2332,7 +2387,9 @@ AVCodec ff_theora_decoder = { vp3_decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, NULL, + .flush = vp3_decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Theora"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; #endif @@ -2348,6 +2405,8 @@ AVCodec ff_vp3_decoder = { vp3_decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, NULL, + .flush = vp3_decode_flush, .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index e9de38e6dd..ba4a9d290a 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -47,14 +47,19 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, { vp56_rac_gets(c, 8); if(vp56_rac_gets(c, 5) > 5) - return 0; + return AVERROR_INVALIDDATA; vp56_rac_gets(c, 2); if (vp56_rac_get(c)) { av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); - return 0; + return AVERROR_PATCHWELCOME; } rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ + if (!rows || !cols) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", + cols << 4, rows << 4); + return AVERROR_INVALIDDATA; + } vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ vp56_rac_gets(c, 2); @@ -62,11 +67,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); - return 2; + return VP56_SIZE_CHANGE; } } else if (!s->macroblocks) - return 0; - return 1; + return AVERROR_INVALIDDATA; + return 0; } static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect) @@ -116,7 +121,7 @@ static void vp5_parse_vector_models(VP56Context *s) model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); } -static void vp5_parse_coeff_models(VP56Context *s) +static int vp5_parse_coeff_models(VP56Context *s) { VP56RangeCoder *c = &s->c; VP56Model *model = s->modelp; @@ -160,6 +165,7 @@ static void vp5_parse_coeff_models(VP56Context *s) for (ctx=0; ctx<6; ctx++) for (node=0; node<5; node++) model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); + return 0; } static void vp5_parse_coeff(VP56Context *s) @@ -182,7 +188,8 @@ static void vp5_parse_coeff(VP56Context *s) model1 = model->coeff_dccv[pt]; model2 = model->coeff_dcct[pt][ctx]; - for (coeff_idx=0; coeff_idx<64; ) { + coeff_idx = 0; + for (;;) { if (vp56_rac_get_prob(c, model2[0])) { if (vp56_rac_get_prob(c, model2[2])) { if (vp56_rac_get_prob(c, model2[3])) { @@ -219,8 +226,11 @@ static void vp5_parse_coeff(VP56Context *s) ct = 0; s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0; } + coeff_idx++; + if (coeff_idx >= 64) + break; - cg = vp5_coeff_groups[++coeff_idx]; + cg = vp5_coeff_groups[coeff_idx]; ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; model1 = model->coeff_ract[pt][ct][cg]; model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx]; diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index ad451c251f..7503876d2d 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -399,6 +399,8 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) frame_current = s->framep[VP56_FRAME_CURRENT]; frame_ref = s->framep[ref_frame]; + if (mb_type != VP56_MB_INTRA && !frame_ref->data[0]) + return; ab = 6*is_alpha; b_max = 6 - 2*is_alpha; @@ -463,6 +465,7 @@ static int vp56_size_changed(AVCodecContext *avctx) s->mb_height = (avctx->coded_height+15) / 16; if (s->mb_width > 1000 || s->mb_height > 1000) { + avcodec_set_dimensions(avctx, 0, 0); av_log(avctx, AV_LOG_ERROR, "picture too big\n"); return -1; } @@ -508,8 +511,26 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, s->modelp = &s->models[is_alpha]; res = s->parse_header(s, buf, remaining_buf_size, &golden_frame); - if (!res) - return -1; + if (res < 0) { + int i; + for (i = 0; i < 4; i++) { + if (s->frames[i].data[0]) + avctx->release_buffer(avctx, &s->frames[i]); + } + return res; + } + + if (res == VP56_SIZE_CHANGE) { + int i; + for (i = 0; i < 4; i++) { + if (s->frames[i].data[0]) + avctx->release_buffer(avctx, &s->frames[i]); + } + if (is_alpha) { + avcodec_set_dimensions(avctx, 0, 0); + return -1; + } + } if (!is_alpha) { p->reference = 1; @@ -518,7 +539,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return -1; } - if (res == 2) + if (res == VP56_SIZE_CHANGE) if (vp56_size_changed(avctx)) { avctx->release_buffer(avctx, p); return -1; @@ -537,7 +558,8 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, s->mb_type = VP56_MB_INTER_NOVEC_PF; } - s->parse_coeff_models(s); + if (s->parse_coeff_models(s)) + goto next; memset(s->prev_dc, 0, sizeof(s->prev_dc)); s->prev_dc[1][VP56_FRAME_CURRENT] = 128; @@ -601,6 +623,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } } + next: if (p->key_frame || golden_frame) { if (s->framep[VP56_FRAME_GOLDEN]->data[0] && s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index d1735e5609..0bec36fc81 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -38,6 +38,8 @@ typedef struct { int16_t y; } DECLARE_ALIGNED(4, , VP56mv); +#define VP56_SIZE_CHANGE 1 + typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, VP56mv *vect); typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, @@ -46,7 +48,7 @@ typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, typedef void (*VP56ParseCoeff)(VP56Context *s); typedef void (*VP56DefaultModelsInit)(VP56Context *s); typedef void (*VP56ParseVectorModels)(VP56Context *s); -typedef void (*VP56ParseCoeffModels)(VP56Context *s); +typedef int (*VP56ParseCoeffModels)(VP56Context *s); typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf, int buf_size, int *golden_frame); diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index 0a02ce58d6..11c763bd83 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -50,7 +50,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, int vrt_shift = 0; int sub_version; int rows, cols; - int res = 1; + int res = 0; int separated_coeff = buf[0] & 1; s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); @@ -59,11 +59,11 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, if (s->framep[VP56_FRAME_CURRENT]->key_frame) { sub_version = buf[1] >> 3; if (sub_version > 8) - return 0; + return AVERROR_INVALIDDATA; s->filter_header = buf[1] & 0x06; if (buf[1] & 1) { - av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); - return 0; + av_log_missing_feature(s->avctx, "Interlacing", 0); + return AVERROR_PATCHWELCOME; } if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+2) - 2; @@ -75,6 +75,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, cols = buf[3]; /* number of stored macroblock cols */ /* buf[4] is number of displayed macroblock rows */ /* buf[5] is number of displayed macroblock cols */ + if (!rows || !cols) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4); + return AVERROR_INVALIDDATA; + } if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || @@ -84,7 +88,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, s->avctx->width -= s->avctx->extradata[0] >> 4; s->avctx->height -= s->avctx->extradata[0] & 0x0F; } - res = 2; + res = VP56_SIZE_CHANGE; } ff_vp56_init_range_decoder(c, buf+6, buf_size-6); @@ -95,8 +99,8 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, vrt_shift = 5; s->sub_version = sub_version; } else { - if (!s->sub_version) - return 0; + if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height) + return AVERROR_INVALIDDATA; if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+1) - 2; @@ -137,8 +141,11 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, if (coeff_offset) { buf += coeff_offset; buf_size -= coeff_offset; - if (buf_size < 0) - return 0; + if (buf_size < 0) { + if (s->framep[VP56_FRAME_CURRENT]->key_frame) + avcodec_set_dimensions(s->avctx, 0, 0); + return AVERROR_INVALIDDATA; + } if (s->use_huffman) { s->parse_coeff = vp6_parse_coeff_huffman; init_get_bits(&s->gb, buf, buf_size<<3); @@ -213,8 +220,8 @@ static int vp6_huff_cmp(const void *va, const void *vb) return (a->count - b->count)*16 + (b->sym - a->sym); } -static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], - const uint8_t *map, unsigned size, VLC *vlc) +static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], + const uint8_t *map, unsigned size, VLC *vlc) { Node nodes[2*VP6_MAX_HUFF_SIZE], *tmp = &nodes[size]; int a, b, i; @@ -229,12 +236,12 @@ static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], } free_vlc(vlc); - /* then build the huffman tree accodring to probabilities */ - ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, - FF_HUFFMAN_FLAG_HNODE_FIRST); + /* then build the huffman tree according to probabilities */ + return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, + FF_HUFFMAN_FLAG_HNODE_FIRST); } -static void vp6_parse_coeff_models(VP56Context *s) +static int vp6_parse_coeff_models(VP56Context *s) { VP56RangeCoder *c = &s->c; VP56Model *model = s->modelp; @@ -279,15 +286,18 @@ static void vp6_parse_coeff_models(VP56Context *s) if (s->use_huffman) { for (pt=0; pt<2; pt++) { - vp6_build_huff_tree(s, model->coeff_dccv[pt], - vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]); - vp6_build_huff_tree(s, model->coeff_runv[pt], - vp6_huff_run_map, 9, &s->runv_vlc[pt]); + if (vp6_build_huff_tree(s, model->coeff_dccv[pt], + vp6_huff_coeff_map, 12, &s->dccv_vlc[pt])) + return -1; + if (vp6_build_huff_tree(s, model->coeff_runv[pt], + vp6_huff_run_map, 9, &s->runv_vlc[pt])) + return -1; for (ct=0; ct<3; ct++) for (cg = 0; cg < 6; cg++) - vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], - vp6_huff_coeff_map, 12, - &s->ract_vlc[pt][ct][cg]); + if (vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], + vp6_huff_coeff_map, 12, + &s->ract_vlc[pt][ct][cg])) + return -1; } memset(s->nb_null, 0, sizeof(s->nb_null)); } else { @@ -297,6 +307,7 @@ static void vp6_parse_coeff_models(VP56Context *s) for (node=0; node<5; node++) model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); } + return 0; } static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect) @@ -367,7 +378,7 @@ static void vp6_parse_coeff_huffman(VP56Context *s) if (b > 3) pt = 1; vlc_coeff = &s->dccv_vlc[pt]; - for (coeff_idx=0; coeff_idx<64; ) { + for (coeff_idx = 0;;) { int run = 1; if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { s->nb_null[coeff_idx][pt]--; @@ -404,6 +415,8 @@ static void vp6_parse_coeff_huffman(VP56Context *s) } } coeff_idx+=run; + if (coeff_idx >= 64) + break; cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); vlc_coeff = &s->ract_vlc[pt][ct][cg]; } @@ -431,7 +444,8 @@ static void vp6_parse_coeff(VP56Context *s) model1 = model->coeff_dccv[pt]; model2 = model->coeff_dcct[pt][ctx]; - for (coeff_idx=0; coeff_idx<64; ) { + coeff_idx = 0; + for (;;) { if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { /* parse a coeff */ if (vp56_rac_get_prob(c, model2[2])) { @@ -472,8 +486,10 @@ static void vp6_parse_coeff(VP56Context *s) run += vp56_rac_get_prob(c, model3[i+8]) << i; } } - - cg = vp6_coeff_groups[coeff_idx+=run]; + coeff_idx += run; + if (coeff_idx >= 64) + break; + cg = vp6_coeff_groups[coeff_idx]; model1 = model2 = model->coeff_ract[pt][ct][cg]; } diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 082d8e5829..24f4d2fce8 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -33,6 +33,19 @@ # include "arm/vp8.h" #endif +static void free_buffers(VP8Context *s) +{ + av_freep(&s->macroblocks_base); + av_freep(&s->filter_strength); + av_freep(&s->intra4x4_pred_mode_top); + av_freep(&s->top_nnz); + av_freep(&s->edge_emu_buffer); + av_freep(&s->top_border); + av_freep(&s->segmentation_map); + + s->macroblocks = NULL; +} + static void vp8_decode_flush(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; @@ -45,15 +58,7 @@ static void vp8_decode_flush(AVCodecContext *avctx) } memset(s->framep, 0, sizeof(s->framep)); - av_freep(&s->macroblocks_base); - av_freep(&s->filter_strength); - av_freep(&s->intra4x4_pred_mode_top); - av_freep(&s->top_nnz); - av_freep(&s->edge_emu_buffer); - av_freep(&s->top_border); - av_freep(&s->segmentation_map); - - s->macroblocks = NULL; + free_buffers(s); } static int update_dimensions(VP8Context *s, int width, int height) @@ -269,11 +274,12 @@ static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size) memcpy(s->prob->pred8x8c , vp8_pred8x8c_prob_inter , sizeof(s->prob->pred8x8c)); memcpy(s->prob->mvc , vp8_mv_default_prob , sizeof(s->prob->mvc)); memset(&s->segmentation, 0, sizeof(s->segmentation)); + memset(&s->lf_delta, 0, sizeof(s->lf_delta)); } if (!s->macroblocks_base || /* first frame */ width != s->avctx->width || height != s->avctx->height) { - if ((ret = update_dimensions(s, width, height) < 0)) + if ((ret = update_dimensions(s, width, height)) < 0) return ret; } @@ -487,6 +493,7 @@ void decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y) AV_ZERO32(&near_mv[0]); AV_ZERO32(&near_mv[1]); + AV_ZERO32(&near_mv[2]); /* Process MB on top, left and top-left */ #define MV_EDGE_CHECK(n)\ @@ -641,8 +648,6 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_ * @param block destination for block coefficients * @param probs probabilities to use when reading trees from the bitstream * @param i initial coeff index, 0 unless a separate DC block is coded - * @param zero_nhood the initial prediction context for number of surrounding - * all-zero blocks (only left/top, so 0-2) * @param qmul array holding the dc/ac dequant factor at position 0/1 * @return 0 if no coeffs were decoded * otherwise, the index of the last coeff decoded plus one @@ -701,6 +706,17 @@ skip_eob: } #endif +/** + * @param c arithmetic bitstream reader context + * @param block destination for block coefficients + * @param probs probabilities to use when reading trees from the bitstream + * @param i initial coeff index, 0 unless a separate DC block is coded + * @param zero_nhood the initial prediction context for number of surrounding + * all-zero blocks (only left/top, so 0-2) + * @param qmul array holding the dc/ac dequant factor at position 0/1 + * @return 0 if no coeffs were decoded + * otherwise, the index of the last coeff decoded plus one + */ static av_always_inline int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16], uint8_t probs[16][3][NUM_DCT_TOKENS-1], @@ -910,7 +926,8 @@ void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb, int mb_x, int mb_y) { AVCodecContext *avctx = s->avctx; - int x, y, mode, nnz, tr; + int x, y, mode, nnz; + uint32_t tr; // for the first row, we need to run xchg_mb_border to init the top edge to 127 // otherwise, skip it if we aren't going to deblock @@ -939,7 +956,7 @@ void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb, // from the top macroblock if (!(!mb_y && avctx->flags & CODEC_FLAG_EMU_EDGE) && mb_x == s->mb_width-1) { - tr = tr_right[-1]*0x01010101; + tr = tr_right[-1]*0x01010101u; tr_right = (uint8_t *)&tr; } @@ -1034,10 +1051,9 @@ static const uint8_t subpel_idx[3][8] = { }; /** - * Generic MC function. + * luma MC function * * @param s VP8 decoding context - * @param luma 1 for luma (Y) planes, 0 for chroma (Cb/Cr) planes * @param dst target buffer for block data at block position * @param src reference picture buffer at origin (0, 0) * @param mv motion vector (relative to block position) to get pixel data from @@ -1083,6 +1099,23 @@ void vp8_mc_luma(VP8Context *s, uint8_t *dst, AVFrame *ref, const VP56mv *mv, } } +/** + * chroma MC function + * + * @param s VP8 decoding context + * @param dst1 target buffer for block data at block position (U plane) + * @param dst2 target buffer for block data at block position (V plane) + * @param ref reference picture buffer at origin (0, 0) + * @param mv motion vector (relative to block position) to get pixel data from + * @param x_off horizontal position of block from origin (0, 0) + * @param y_off vertical position of block from origin (0, 0) + * @param block_w width of block (16, 8 or 4) + * @param block_h height of block (always same as block_w) + * @param width width of src/dst plane data + * @param height height of src/dst plane data + * @param linesize size of a single line of plane data, including padding + * @param mc_func motion compensation function pointers (bilinear or sixtap MC) + */ static av_always_inline void vp8_mc_chroma(VP8Context *s, uint8_t *dst1, uint8_t *dst2, AVFrame *ref, const VP56mv *mv, int x_off, int y_off, @@ -1724,6 +1757,11 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo { VP8Context *s = dst->priv_data, *s_src = src->priv_data; + if (s->macroblocks_base && + (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) { + free_buffers(s); + } + s->prob[0] = s_src->prob[!s_src->update_probabilities]; s->segmentation = s_src->segmentation; s->lf_delta = s_src->lf_delta; diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index ca4fd94d75..e7b2cae26a 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -138,6 +138,10 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) /* load up the VQA parameters from the header */ vqa_header = (unsigned char *)s->avctx->extradata; s->vqa_version = vqa_header[0]; + if (s->vqa_version < 1 || s->vqa_version > 3) { + av_log(s->avctx, AV_LOG_ERROR, " VQA video: unsupported version %d\n", s->vqa_version); + return -1; + } s->width = AV_RL16(&vqa_header[6]); s->height = AV_RL16(&vqa_header[8]); if(av_image_check_size(s->width, s->height, 0, avctx)){ @@ -155,6 +159,12 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) return -1; } + if (s->width & (s->vector_width - 1) || + s->height & (s->vector_height - 1)) { + av_log(avctx, AV_LOG_ERROR, "Image size not multiple of block size\n"); + return AVERROR_INVALIDDATA; + } + /* allocate codebooks */ s->codebook_size = MAX_CODEBOOK_SIZE; s->codebook = av_malloc(s->codebook_size); @@ -226,6 +236,8 @@ static void decode_format80(const unsigned char *src, int src_size, src_index += 2; av_dlog(NULL, "(1) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); + if (src_pos + count > dest_size) + return; for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; @@ -248,6 +260,8 @@ static void decode_format80(const unsigned char *src, int src_size, src_index += 2; av_dlog(NULL, "(3) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); + if (src_pos + count > dest_size) + return; for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; @@ -268,6 +282,8 @@ static void decode_format80(const unsigned char *src, int src_size, src_index += 2; av_dlog(NULL, "(5) copy %X bytes from relpos %X\n", count, src_pos); CHECK_COUNT(); + if (dest_index < src_pos) + return; for (i = 0; i < count; i++) dest[dest_index + i] = dest[dest_index - src_pos + i]; dest_index += count; @@ -511,6 +527,11 @@ static void vqa_decode_chunk(VqaContext *s) chunk_size = AV_RB32(&s->buf[cbp0_chunk + 4]); cbp0_chunk += CHUNK_PREAMBLE_SIZE; + if (chunk_size > MAX_CODEBOOK_SIZE - s->next_codebook_buffer_index) { + av_log(s->avctx, AV_LOG_ERROR, "cbp0 chunk too large (0x%X bytes)\n", chunk_size); + return; + } + /* accumulate partial codebook */ memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], &s->buf[cbp0_chunk], chunk_size); @@ -534,6 +555,11 @@ static void vqa_decode_chunk(VqaContext *s) chunk_size = AV_RB32(&s->buf[cbpz_chunk + 4]); cbpz_chunk += CHUNK_PREAMBLE_SIZE; + if (chunk_size > MAX_CODEBOOK_SIZE - s->next_codebook_buffer_index) { + av_log(s->avctx, AV_LOG_ERROR, "cbpz chunk too large (0x%X bytes)\n", chunk_size); + return; + } + /* accumulate partial codebook */ memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], &s->buf[cbpz_chunk], chunk_size); diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index d5102320fd..28e866356d 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -292,7 +292,14 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel } }else{ t = get_unary_0_33(gb); - if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1)); + if(t >= 2){ + if(get_bits_left(gb) < t-1) + goto error; + t = get_bits(gb, t - 1) | (1 << (t-1)); + }else{ + if(get_bits_left(gb) < 0) + goto error; + } ctx->zeroes = t; if(ctx->zeroes){ memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median)); @@ -303,24 +310,24 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel } } - if(get_bits_count(gb) >= ctx->data_size){ - *last = 1; - return 0; - } - if(ctx->zero){ t = 0; ctx->zero = 0; }else{ t = get_unary_0_33(gb); - if(get_bits_count(gb) >= ctx->data_size){ - *last = 1; - return 0; - } + if(get_bits_left(gb) < 0) + goto error; if(t == 16) { t2 = get_unary_0_33(gb); - if(t2 < 2) t += t2; - else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + if(t2 < 2){ + if(get_bits_left(gb) < 0) + goto error; + t += t2; + }else{ + if(get_bits_left(gb) < t2 - 1) + goto error; + t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + } } if(ctx->one){ @@ -360,9 +367,13 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel } if(!c->error_limit){ ret = base + get_tail(gb, add); + if (get_bits_left(gb) <= 0) + goto error; }else{ int mid = (base*2 + add + 1) >> 1; while(add > c->error_limit){ + if(get_bits_left(gb) <= 0) + goto error; if(get_bits1(gb)){ add -= (mid - base); base = mid; @@ -376,6 +387,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel if(ctx->hybrid_bitrate) c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level); return sign ? ~ret : ret; + +error: + *last = 1; + return 0; } static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, int S) @@ -385,7 +400,7 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in if(s->extra_bits){ S <<= s->extra_bits; - if(s->got_extra_bits){ + if(s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits){ S |= get_bits(&s->gb_extra_bits, s->extra_bits); *crc = *crc * 9 + (S&0xffff) * 3 + ((unsigned)S>>16); } @@ -580,7 +595,10 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo count++; }while(!last && count < s->max_samples); - s->samples_left -= count; + if (last) + s->samples_left = 0; + else + s->samples_left -= count; if(!s->samples_left){ if(crc != s->CRC){ av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); @@ -658,7 +676,10 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void count++; }while(!last && count < s->max_samples); - s->samples_left -= count; + if (last) + s->samples_left = 0; + else + s->samples_left -= count; if(!s->samples_left){ if(crc != s->CRC){ av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); @@ -779,7 +800,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->samples = AV_RL32(buf); buf += 4; if(!s->samples){ *data_size = 0; - return buf_size; + return 0; } }else{ s->samples = wc->samples; @@ -841,12 +862,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } switch(id & WP_IDF_MASK){ case WP_ID_DECTERMS: - s->terms = size; - if(s->terms > MAX_TERMS){ + if(size > MAX_TERMS){ av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n"); + s->terms = 0; buf += 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; @@ -1098,6 +1120,10 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S32); else samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); + + if (samplecount < 0) + return -1; + samplecount >>= 1; }else{ const int channel_stride = avctx->channels; @@ -1109,6 +1135,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, else samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); + if (samplecount < 0) + return -1; + if(s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16){ int16_t *dst = (int16_t*)samples + 1; int16_t *src = (int16_t*)samples; @@ -1144,6 +1173,15 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, return samplecount * bpp; } +static void wavpack_decode_flush(AVCodecContext *avctx) +{ + WavpackContext *s = avctx->priv_data; + int i; + + for (i = 0; i < s->fdec_num; i++) + wv_reset_saved_context(s->fdec[i]); +} + static int wavpack_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) @@ -1176,11 +1214,14 @@ static int wavpack_decode_frame(AVCodecContext *avctx, if(frame_size < 0 || frame_size > buf_size){ av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d vs. %d bytes left)\n", s->block, frame_size, buf_size); + wavpack_decode_flush(avctx); return -1; } if((samplecount = wavpack_decode_block(avctx, s->block, data, - data_size, buf, frame_size)) < 0) + data_size, buf, frame_size)) < 0) { + wavpack_decode_flush(avctx); return -1; + } s->block++; buf += frame_size; buf_size -= frame_size; } diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 67599b7eab..2e8ac979a5 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -85,7 +85,7 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version, } else if (sample_rate <= 22050 || (sample_rate <= 32000 && version == 1)) { frame_len_bits = 10; - } else if (sample_rate <= 48000) { + } else if (sample_rate <= 48000 || version < 3) { frame_len_bits = 11; } else if (sample_rate <= 96000) { frame_len_bits = 12; @@ -137,6 +137,9 @@ int ff_wma_init(AVCodecContext *avctx, int flags2) /* compute MDCT block size */ s->frame_len_bits = ff_wma_get_frame_len_bits(s->sample_rate, s->version, 0); + s->next_block_len_bits = s->frame_len_bits; + s->prev_block_len_bits = s->frame_len_bits; + s->block_len_bits = s->frame_len_bits; s->frame_len = 1 << s->frame_len_bits; if (s->use_variable_block_len) { @@ -174,6 +177,10 @@ int ff_wma_init(AVCodecContext *avctx, int flags2) bps = (float)s->bit_rate / (float)(s->nb_channels * s->sample_rate); s->byte_offset_bits = av_log2((int)(bps * s->frame_len / 8.0 + 0.5)) + 2; + if (s->byte_offset_bits + 3 > MIN_CACHE_BITS) { + av_log(avctx, AV_LOG_ERROR, "byte_offset_bits %d is too large\n", s->byte_offset_bits); + return AVERROR_PATCHWELCOME; + } /* compute high frequency value and choose if noise coding should be activated */ diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 9eaf230b01..16ef54e378 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -85,6 +85,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 */ @@ -109,6 +114,11 @@ static int wma_decode_init(AVCodecContext * avctx) } } + if(avctx->channels > MAX_CHANNELS){ + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels (%d)\n", avctx->channels); + return -1; + } + if(ff_wma_init(avctx, flags2)<0) return -1; @@ -359,7 +369,7 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) } /* NOTE: this offset is the same as MPEG4 AAC ! */ last_exp += code - 60; - if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) { + if ((unsigned)last_exp + 60 >= FF_ARRAY_ELEMS(pow_tab)) { av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n", last_exp); return -1; @@ -877,6 +887,8 @@ static int wma_decode_superframe(AVCodecContext *avctx, /* read each frame starting from bit_offset */ pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; + if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8) + return AVERROR_INVALIDDATA; init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); len = pos & 7; if (len > 0) diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 0bafe1a64d..0a3264afc6 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -39,6 +39,12 @@ static int encode_init(AVCodecContext * avctx){ return AVERROR(EINVAL); } + if (avctx->sample_rate > 48000) { + av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz", + avctx->sample_rate); + return AVERROR(EINVAL); + } + if(avctx->bit_rate < 24*1000) { av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %i, need 24000 or higher\n", avctx->bit_rate); @@ -64,6 +70,8 @@ static int encode_init(AVCodecContext * avctx){ s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; + if (avctx->channels == 2) + s->ms_stereo = 1; ff_wma_init(avctx, flags2); @@ -71,8 +79,12 @@ static int encode_init(AVCodecContext * avctx){ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); - avctx->block_align= - s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8); + s->block_align = avctx->bit_rate * (int64_t)s->frame_len / + (avctx->sample_rate * 8); + s->block_align = FFMIN(s->block_align, MAX_CODED_SUPERFRAME_SIZE); + avctx->block_align = s->block_align; + avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate / + s->frame_len; //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate); avctx->frame_size= s->frame_len; @@ -181,7 +193,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], } if (s->nb_channels == 2) { - put_bits(&s->pb, 1, s->ms_stereo= 1); + put_bits(&s->pb, 1, !!s->ms_stereo); } for(ch = 0; ch < s->nb_channels; ch++) { @@ -355,6 +367,11 @@ static int encode_superframe(AVCodecContext *avctx, } } + if (buf_size < 2 * MAX_CODED_SUPERFRAME_SIZE) { + av_log(avctx, AV_LOG_ERROR, "output buffer size is too small\n"); + return AVERROR(EINVAL); + } + #if 1 total_gain= 128; for(i=64; i; i>>=1){ diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index e1d942dca2..67c62a4da0 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -277,6 +277,11 @@ static av_cold int decode_init(AVCodecContext *avctx) int log2_max_num_subframes; int num_possible_block_sizes; + if (!avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "block_align is not set\n"); + return AVERROR(EINVAL); + } + s->avctx = avctx; dsputil_init(&s->dsp, avctx); init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); @@ -309,10 +314,6 @@ static av_cold int decode_init(AVCodecContext *avctx) s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, 3, s->decode_flags); - /** init previous block len */ - for (i = 0; i < avctx->channels; i++) - s->channel[i].prev_block_len = s->samples_per_frame; - /** subframe info */ log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3); s->max_num_subframes = 1 << log2_max_num_subframes; @@ -330,8 +331,25 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + if (s->avctx->sample_rate <= 0) { + av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); + return AVERROR_INVALIDDATA; + } + s->num_channels = avctx->channels; + if (s->num_channels < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels); + return AVERROR_INVALIDDATA; + } else if (s->num_channels > WMAPRO_MAX_CHANNELS) { + av_log_ask_for_sample(avctx, "unsupported number of channels\n"); + return AVERROR_PATCHWELCOME; + } + + /** init previous block len */ + for (i = 0; i < s->num_channels; i++) + s->channel[i].prev_block_len = s->samples_per_frame; + /** extract lfe channel position */ s->lfe_channel = -1; @@ -343,14 +361,6 @@ static av_cold int decode_init(AVCodecContext *avctx) } } - if (s->num_channels < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels); - return AVERROR_INVALIDDATA; - } else if (s->num_channels > WMAPRO_MAX_CHANNELS) { - av_log_ask_for_sample(avctx, "unsupported number of channels\n"); - return AVERROR_PATCHWELCOME; - } - INIT_VLC_STATIC(&sf_vlc, SCALEVLCBITS, HUFF_SCALE_SIZE, scale_huffbits, 1, 1, scale_huffcodes, 2, 2, 616); @@ -394,6 +404,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; @@ -1158,7 +1171,12 @@ static int decode_subframe(WMAProDecodeCtx *s) int num_bits = av_log2((s->subframe_len + 3)/4) + 1; for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + if (num_vec_coeffs > WMAPRO_BLOCK_MAX_SIZE) { + av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); + return AVERROR_INVALIDDATA; + } + s->channel[c].num_vec_coeffs = num_vec_coeffs; } } else { for (i = 0; i < s->channels_for_cur_subframe; i++) { @@ -1436,7 +1454,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } - buflen = (s->num_saved_bits + len + 8) >> 3; + buflen = (put_bits_count(&s->pb) + len + 8) >> 3; if (len <= 0 || buflen > MAX_FRAMESIZE) { av_log_ask_for_sample(s->avctx, "input buffer too small\n"); @@ -1492,8 +1510,11 @@ static int decode_packet(AVCodecContext *avctx, 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 3604eac782..22273527af 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -128,9 +128,7 @@ static const struct frame_type_desc { */ typedef struct { /** - * @defgroup struct_global Global values - * Global values, specified in the stream header / extradata or used - * all over. + * @name Global values specified in the stream header / extradata or used all over. * @{ */ GetBitContext gb; ///< packet bitreader. During decoder init, @@ -182,8 +180,9 @@ typedef struct { /** * @} - * @defgroup struct_packet Packet values - * Packet values, specified in the packet header or related to a packet. + * + * @name Packet values specified in the packet header or related to a packet. + * * A packet is considered to be a single unit of data provided to this * decoder by the demuxer. * @{ @@ -213,7 +212,8 @@ typedef struct { /** * @} - * @defgroup struct_frame Frame and superframe values + * + * @name Frame and superframe values * Superframe and frame data - these can change from frame to frame, * although some of them do in that case serve as a cache / history for * the next frame or superframe. @@ -256,7 +256,9 @@ typedef struct { float synth_history[MAX_LSPS]; ///< see #excitation_history /** * @} - * @defgroup post_filter Postfilter values + * + * @name Postfilter values + * * Variables used for postfilter implementation, mostly history for * smoothing and so on, and context variables for FFT/iFFT. * @{ @@ -399,6 +401,10 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->min_pitch_val = ((ctx->sample_rate << 8) / 400 + 50) >> 8; s->max_pitch_val = ((ctx->sample_rate << 8) * 37 / 2000 + 50) >> 8; pitch_range = s->max_pitch_val - s->min_pitch_val; + if (pitch_range <= 0) { + av_log(ctx, AV_LOG_ERROR, "Invalid pitch range; broken extradata?\n"); + return -1; + } s->pitch_nbits = av_ceil_log2(pitch_range); s->last_pitch_val = 40; s->last_acb_type = ACB_TYPE_NONE; @@ -420,6 +426,10 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->block_conv_table[2] = (pitch_range * 44) >> 6; s->block_conv_table[3] = s->max_pitch_val - 1; s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF; + if (s->block_delta_pitch_hrange <= 0) { + av_log(ctx, AV_LOG_ERROR, "Invalid delta pitch hrange; broken extradata?\n"); + return -1; + } s->block_delta_pitch_nbits = 1 + av_ceil_log2(s->block_delta_pitch_hrange); s->block_pitch_range = s->block_conv_table[2] + s->block_conv_table[3] + 1 + @@ -432,7 +442,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) } /** - * @defgroup postfilter Postfilter functions + * @name Postfilter functions * Postfilter functions (gain control, wiener denoise filter, DC filter, * kalman smoothening, plus surrounding code to wrap it) * @{ @@ -825,7 +835,7 @@ static void dequant_lsps(double *lsps, int num, } /** - * @defgroup lsp_dequant LSP dequantization routines + * @name LSP dequantization routines * LSP dequantization routines, for 10/16LSPs and independent/residual coding. * @note we assume enough bits are available, caller should check. * lsp10i() consumes 24 bits; lsp10r() consumes an additional 24 bits; @@ -969,7 +979,7 @@ static void dequant_lsp16r(GetBitContext *gb, /** * @} - * @defgroup aw Pitch-adaptive window coding functions + * @name Pitch-adaptive window coding functions * The next few functions are for pitch-adaptive window coding. * @{ */ @@ -1075,7 +1085,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, int excl_range = s->aw_pulse_range; // always 16 or 24 uint16_t *use_mask_ptr = &use_mask[idx >> 4]; int first_sh = 16 - (idx & 15); - *use_mask_ptr++ &= 0xFFFF << first_sh; + *use_mask_ptr++ &= 0xFFFFu << first_sh; excl_range -= first_sh; if (excl_range >= 16) { *use_mask_ptr++ = 0; @@ -1878,6 +1888,8 @@ static void copy_bits(PutBitContext *pb, rmn_bits = rmn_bytes = get_bits_left(gb); if (rmn_bits < nbits) return; + if (nbits > pb->size_in_bits - put_bits_count(pb)) + return; rmn_bits &= 7; rmn_bytes >>= 3; if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0) put_bits(pb, rmn_bits, get_bits(gb, rmn_bits)); diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c index 4a074e674c..ca930b94f6 100644 --- a/libavcodec/wmv2enc.c +++ b/libavcodec/wmv2enc.c @@ -171,7 +171,7 @@ void ff_wmv2_encode_mb(MpegEncContext * s, wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); } else { diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index 197cf7985d..4947ea5598 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -70,6 +70,11 @@ static int decode_frame(AVCodecContext *avctx, int prev_y = 0, prev_u = 0, prev_v = 0; uint8_t *rbuf; + if(buf_size<=8) { + av_log(avctx, AV_LOG_ERROR, "buf_size %d is too small\n", buf_size); + return AVERROR_INVALIDDATA; + } + rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!rbuf){ av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index d6a60d441f..c28d1a8d6a 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -37,13 +37,16 @@ static const int8_t ws_adpcm_4bit[] = { -9, -8, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 8 }; -#define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128; - static av_cold int ws_snd_decode_init(AVCodecContext * avctx) { // WSSNDContext *c = avctx->priv_data; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (avctx->channels != 1) { + av_log_ask_for_sample(avctx, "unsupported number of channels\n"); + return AVERROR(EINVAL); + } + + avctx->sample_fmt = AV_SAMPLE_FMT_U8; return 0; } @@ -56,15 +59,19 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, // WSSNDContext *c = avctx->priv_data; int in_size, out_size; - int sample = 0; + int sample = 128; int i; - short *samples = data; + uint8_t *samples = data; if (!buf_size) return 0; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + out_size = AV_RL16(&buf[0]); - *data_size = out_size * 2; in_size = AV_RL16(&buf[2]); buf += 4; @@ -76,34 +83,54 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n"); return -1; } + if (in_size == out_size) { for (i = 0; i < out_size; i++) - *samples++ = (*buf++ - 0x80) << 8; + *samples++ = *buf++; + *data_size = out_size; return buf_size; } - while (out_size > 0) { - int code; + while (out_size > 0 && buf - avpkt->data < buf_size) { + int code, smp, size; uint8_t count; code = (*buf) >> 6; count = (*buf) & 0x3F; buf++; + + /* make sure we don't write more than out_size samples */ + switch (code) { + case 0: smp = 4*(count+1); break; + case 1: smp = 2*(count+1); break; + case 2: smp = (count & 0x20) ? 1 : count + 1; break; + default: smp = count + 1; break; + } + if (out_size < smp) { + out_size = 0; + break; + } + + /* make sure we don't read past the input buffer */ + size = ((code == 2 && (count & 0x20)) || code == 3) ? 0 : count + 1; + if ((buf - avpkt->data) + size > buf_size) + break; + switch(code) { case 0: /* ADPCM 2-bit */ for (count++; count > 0; count--) { code = *buf++; sample += ws_adpcm_2bit[code & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 2) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 4) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 6) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size -= 4; } break; @@ -111,11 +138,11 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, for (count++; count > 0; count--) { code = *buf++; sample += ws_adpcm_4bit[code & 0xF]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_4bit[code >> 4]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size -= 2; } break; @@ -125,24 +152,27 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, t = count; t <<= 3; sample += t >> 3; - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size--; } else { /* copy */ for (count++; count > 0; count--) { - *samples++ = (*buf++ - 0x80) << 8; + *samples++ = *buf++; out_size--; } - sample = buf[-1] - 0x80; + sample = buf[-1]; } break; default: /* run */ for(count++; count > 0; count--) { - *samples++ = sample << 8; + *samples++ = sample; out_size--; } } } + *data_size = samples - (uint8_t *)data; + return buf_size; } diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm index 695aba5ec3..a114153585 100644 --- a/libavcodec/x86/dsputil_yasm.asm +++ b/libavcodec/x86/dsputil_yasm.asm @@ -474,7 +474,7 @@ cglobal scalarproduct_float_sse, 3,3,2, v1, v2, offset shufps xmm0, xmm0, 1 addss xmm0, xmm1 %ifndef ARCH_X86_64 - movd r0m, xmm0 + movss r0m, xmm0 fld dword r0m %endif RET diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c index bd31205a6b..0234eaad6e 100644 --- a/libavcodec/x86/dsputilenc_mmx.c +++ b/libavcodec/x86/dsputilenc_mmx.c @@ -823,6 +823,7 @@ static int vsad16_mmx2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, i static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ x86_reg i=0; + if(w>=16) __asm__ volatile( "1: \n\t" "movq (%2, %0), %%mm0 \n\t" diff --git a/libavcodec/x86/fft_3dn2.c b/libavcodec/x86/fft_3dn2.c index 2abb8cfbd7..7a6cac14c4 100644 --- a/libavcodec/x86/fft_3dn2.c +++ b/libavcodec/x86/fft_3dn2.c @@ -23,7 +23,7 @@ #include "libavcodec/dsputil.h" #include "fft.h" -DECLARE_ALIGNED(8, static const int, m1m1)[2] = { 1<<31, 1<<31 }; +DECLARE_ALIGNED(8, static const unsigned int, m1m1)[2] = { 1U<<31, 1U<<31 }; #ifdef EMULATE_3DNOWEXT #define PSWAPD(s,d)\ @@ -70,7 +70,7 @@ void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input in1 = input; in2 = input + n2 - 1; #ifdef EMULATE_3DNOWEXT - __asm__ volatile("movd %0, %%mm7" ::"r"(1<<31)); + __asm__ volatile("movd %0, %%mm7" ::"r"(1U<<31)); #endif for(k = 0; k < n4; k++) { // FIXME a single block is faster, but gcc 2.95 and 3.4.x on 32bit can't compile it diff --git a/libavcodec/x86/fft_sse.c b/libavcodec/x86/fft_sse.c index 26b933c810..43f19fff3b 100644 --- a/libavcodec/x86/fft_sse.c +++ b/libavcodec/x86/fft_sse.c @@ -24,8 +24,8 @@ #include "fft.h" #include "config.h" -DECLARE_ASM_CONST(16, int, ff_m1m1m1m1)[4] = - { 1 << 31, 1 << 31, 1 << 31, 1 << 31 }; +DECLARE_ASM_CONST(16, unsigned int, ff_m1m1m1m1)[4] = + { 1U << 31, 1U << 31, 1U << 31, 1U << 31 }; void ff_fft_dispatch_sse(FFTComplex *z, int nbits); void ff_fft_dispatch_interleave_sse(FFTComplex *z, int nbits); diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm index ee316258d3..dc3a26c355 100644 --- a/libavcodec/x86/h264_deblock_10bit.asm +++ b/libavcodec/x86/h264_deblock_10bit.asm @@ -876,7 +876,7 @@ cglobal deblock_v_chroma_10_%1, 5,7-(mmsize/16),8*(mmsize/16) %if mmsize < 16 add r0, mmsize add r5, mmsize - add r4, mmsize/8 + add r4, mmsize/4 dec r6 jg .loop REP_RET diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c index 486a927ad7..77e3df609e 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/snowdsp_mmx.c b/libavcodec/x86/snowdsp_mmx.c index 9c1fa429a8..f107d55e87 100644 --- a/libavcodec/x86/snowdsp_mmx.c +++ b/libavcodec/x86/snowdsp_mmx.c @@ -675,14 +675,14 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM #define snow_inner_add_yblock_sse2_end_8\ "sal $1, %%"REG_c" \n\t"\ - "add $"PTR_SIZE"*2, %1 \n\t"\ + "add"OPSIZE" $"PTR_SIZE"*2, %1 \n\t"\ snow_inner_add_yblock_sse2_end_common1\ "sar $1, %%"REG_c" \n\t"\ "sub $2, %2 \n\t"\ snow_inner_add_yblock_sse2_end_common2 #define snow_inner_add_yblock_sse2_end_16\ - "add $"PTR_SIZE"*1, %1 \n\t"\ + "add"OPSIZE" $"PTR_SIZE"*1, %1 \n\t"\ snow_inner_add_yblock_sse2_end_common1\ "dec %2 \n\t"\ snow_inner_add_yblock_sse2_end_common2 diff --git a/libavcodec/xan.c b/libavcodec/xan.c index f5d1812aec..5341e0eb70 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -97,20 +97,27 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) return 0; } -static int xan_huffman_decode(unsigned char *dest, const unsigned char *src, - int dest_len) +static int xan_huffman_decode(unsigned char *dest, int dest_len, + const unsigned char *src, int src_len) { unsigned char byte = *src++; unsigned char ival = byte + 0x16; const unsigned char * ptr = src + byte*2; + int ptr_len = src_len - 1 - byte*2; unsigned char val = ival; unsigned char *dest_end = dest + dest_len; GetBitContext gb; - init_get_bits(&gb, ptr, 0); // FIXME: no src size available + if (ptr_len < 0) + return AVERROR_INVALIDDATA; + + init_get_bits(&gb, ptr, ptr_len * 8); while ( val != 0x16 ) { - val = src[val - 0x17 + get_bits1(&gb) * byte]; + unsigned idx = val - 0x17 + get_bits1(&gb) * byte; + if (idx >= 2 * byte) + return -1; + val = src[idx]; if ( val < 0x16 ) { if (dest >= dest_end) @@ -128,13 +135,16 @@ static int xan_huffman_decode(unsigned char *dest, const unsigned char *src, * * @param dest destination buffer of dest_len, must be padded with at least 130 bytes */ -static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len) +static void xan_unpack(unsigned char *dest, int dest_len, + const unsigned char *src, int src_len) { unsigned char opcode; int size; + unsigned char *dest_org = dest; unsigned char *dest_end = dest + dest_len; + const unsigned char *src_end = src + src_len; - while (dest < dest_end) { + while (dest < dest_end && src < src_end) { opcode = *src++; if (opcode < 0xe0) { @@ -159,9 +169,11 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1; size2 = ((opcode & 0x0c) << 6) + *src++ + 5; - if (size + size2 > dest_end - dest) - return; } + if (dest_end - dest < size + size2 || + dest + size - dest_org < back || + src_end - src < size) + return; memcpy(dest, src, size); dest += size; src += size; av_memcpy_backptr(dest, back, size2); dest += size2; @@ -169,6 +181,8 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l int finish = opcode >= 0xfc; size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4; + if (dest_end - dest < size || src_end - src < size) + return; memcpy(dest, src, size); dest += size; src += size; if (finish) return; @@ -216,15 +230,23 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int width = s->avctx->width; unsigned char *palette_plane, *prev_palette_plane; + if ( y + motion_y < 0 || y + motion_y >= s->avctx->height || + x + motion_x < 0 || x + motion_x >= s->avctx->width) + return; + palette_plane = s->current_frame.data[0]; prev_palette_plane = s->last_frame.data[0]; + if (!prev_palette_plane) + prev_palette_plane = palette_plane; stride = s->current_frame.linesize[0]; line_inc = stride - width; curframe_index = y * stride + x; curframe_x = x; prevframe_index = (y + motion_y) * stride + x + motion_x; prevframe_x = x + motion_x; - while(pixel_count && (curframe_index < s->frame_size)) { + while(pixel_count && + curframe_index < s->frame_size && + prevframe_index < s->frame_size) { int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x); memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count); @@ -246,7 +268,7 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, } } -static void xan_wc3_decode_frame(XanContext *s) { +static int xan_wc3_decode_frame(XanContext *s) { int width = s->avctx->width; int height = s->avctx->height; @@ -258,6 +280,7 @@ static void xan_wc3_decode_frame(XanContext *s) { int x, y; unsigned char *opcode_buffer = s->buffer1; + unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size; int opcode_buffer_size = s->buffer1_size; const unsigned char *imagedata_buffer = s->buffer2; @@ -266,22 +289,43 @@ static void xan_wc3_decode_frame(XanContext *s) { const unsigned char *size_segment; const unsigned char *vector_segment; const unsigned char *imagedata_segment; + int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size; - huffman_segment = s->buf + AV_RL16(&s->buf[0]); - size_segment = s->buf + AV_RL16(&s->buf[2]); - vector_segment = s->buf + AV_RL16(&s->buf[4]); - imagedata_segment = s->buf + AV_RL16(&s->buf[6]); + if (s->size < 8) + return AVERROR_INVALIDDATA; - xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size); + huffman_offset = AV_RL16(&s->buf[0]); + size_offset = AV_RL16(&s->buf[2]); + vector_offset = AV_RL16(&s->buf[4]); + imagedata_offset = AV_RL16(&s->buf[6]); - if (imagedata_segment[0] == 2) - xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); - else + if (huffman_offset >= s->size || + size_offset >= s->size || + vector_offset >= s->size || + imagedata_offset >= s->size) + return AVERROR_INVALIDDATA; + + huffman_segment = s->buf + huffman_offset; + size_segment = s->buf + size_offset; + vector_segment = s->buf + vector_offset; + imagedata_segment = s->buf + imagedata_offset; + + if (xan_huffman_decode(opcode_buffer, opcode_buffer_size, + huffman_segment, s->size - huffman_offset) < 0) + return AVERROR_INVALIDDATA; + + if (imagedata_segment[0] == 2) { + xan_unpack(s->buffer2, s->buffer2_size, + &imagedata_segment[1], s->size - imagedata_offset - 1); + imagedata_size = s->buffer2_size; + } else { + imagedata_size = s->size - imagedata_offset - 1; imagedata_buffer = &imagedata_segment[1]; + } /* use the decoded data segments to build the frame */ x = y = 0; - while (total_pixels) { + while (total_pixels && opcode_buffer < opcode_buffer_end) { opcode = *opcode_buffer++; size = 0; @@ -330,6 +374,8 @@ static void xan_wc3_decode_frame(XanContext *s) { size_segment += 3; break; } + if (size > total_pixels) + break; if (opcode < 12) { flag ^= 1; @@ -338,8 +384,11 @@ static void xan_wc3_decode_frame(XanContext *s) { xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); } else { /* output a run of pixels from imagedata_buffer */ + if (imagedata_size < size) + break; xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size); imagedata_buffer += size; + imagedata_size -= size; } } else { /* run-based motion compensation from last frame */ @@ -358,6 +407,7 @@ static void xan_wc3_decode_frame(XanContext *s) { y += (x + size) / width; x = (x + size) % width; } + return 0; } #if RUNTIME_GAMMA @@ -461,6 +511,10 @@ static int xan_decode_frame(AVCodecContext *avctx, int i; tag = bytestream_get_le32(&buf); size = bytestream_get_be32(&buf); + if(size < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size); + return AVERROR_INVALIDDATA; + } size = FFMIN(size, buf_end - buf); switch (tag) { case PALT_TAG: @@ -505,6 +559,11 @@ static int xan_decode_frame(AVCodecContext *avctx, } buf_size = buf_end - buf; } + if (s->palettes_count <= 0) { + av_log(s->avctx, AV_LOG_ERROR, "No palette found\n"); + return AVERROR_INVALIDDATA; + } + if ((ret = avctx->get_buffer(avctx, &s->current_frame))) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; @@ -519,7 +578,8 @@ static int xan_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - xan_wc3_decode_frame(s); + if (xan_wc3_decode_frame(s) < 0) + return AVERROR_INVALIDDATA; /* release the last frame if it is allocated */ if (s->last_frame.data[0]) @@ -564,4 +624,3 @@ AVCodec ff_xan_wc3_decoder = { CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), }; - diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h index 93ad8bb9a5..29c010bff9 100644 --- a/libavcodec/xvmc.h +++ b/libavcodec/xvmc.h @@ -25,6 +25,11 @@ #include "avcodec.h" +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define AV_XVMC_STATE_DISPLAY_PENDING 1 /** the surface should be shown, the video driver manipulates this */ +#define AV_XVMC_STATE_PREDICTION 2 /** the surface is needed for prediction, the codec manipulates this */ +#define AV_XVMC_STATE_OSD_SOURCE 4 /** the surface is needed for subpicture rendering */ +#endif #define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct the number is 1337 speak for the letters IDCT MCo (motion compensation) */ @@ -146,6 +151,22 @@ struct xvmc_pix_fmt { of coded blocks it contains. */ int next_free_data_block_num; + +/** extensions may be placed here */ +#if LIBAVCODEC_VERSION_MAJOR < 53 +//@{ + /** State flags used to work around limitations in the MPlayer video system. + 0 - Surface is not used. + 1 - Surface is still held in application to be displayed or is + still visible. + 2 - Surface is still held in libavcodec buffer for prediction. + */ + int state; + + /** pointer to the surface where the subpicture is rendered */ + void* p_osd_target_surface_render; +//}@ +#endif }; #endif /* AVCODEC_XVMC_H */ diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 10ec53f467..bc35c9542e 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -129,7 +129,9 @@ static int xan_unpack(uint8_t *dest, const int dest_len, if (size + size2 > dest_end - dest) break; } - if (src + size > src_end || dest + size + size2 > dest_end) + if (src + size > src_end || + dest + size + size2 > dest_end || + dest + size - orig_dest < back ) return -1; bytestream_get_buffer(&src, dest, size); dest += size; @@ -194,6 +196,8 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) if (mode) { for (j = 0; j < avctx->height >> 1; j++) { for (i = 0; i < avctx->width >> 1; i++) { + if (src_end - src < 1) + return 0; val = *src++; if (val) { val = AV_RL16(table + (val << 1)); @@ -202,8 +206,6 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) U[i] = uval | (uval >> 5); V[i] = vval | (vval >> 5); } - if (src == src_end) - return 0; } U += s->pic.linesize[1]; V += s->pic.linesize[2]; @@ -214,6 +216,8 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) for (j = 0; j < avctx->height >> 2; j++) { for (i = 0; i < avctx->width >> 1; i += 2) { + if (src_end - src < 1) + return 0; val = *src++; if (val) { val = AV_RL16(table + (val << 1)); @@ -297,11 +301,14 @@ static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) corr_end = avpkt->size; if (chroma_off > corr_off) corr_end = chroma_off; - dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, + dec_size = xan_unpack(s->scratch_buffer, s->buffer_size / 2, avpkt->data + 8 + corr_off, corr_end - corr_off); if (dec_size < 0) dec_size = 0; + else + dec_size = FFMIN(dec_size, s->buffer_size/2 - 1); + for (i = 0; i < dec_size; i++) s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F; } diff --git a/libavcodec/yop.c b/libavcodec/yop.c index 45a3344b9e..bbe78bc0a7 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -90,6 +90,11 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) return -1; } + if (!avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, "extradata missing\n"); + return AVERROR_INVALIDDATA; + } + avctx->pix_fmt = PIX_FMT_PAL8; avcodec_get_frame_defaults(&s->frame); @@ -200,6 +205,11 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); + if (avpkt->size < 4 + 3*s->num_pal_colors) { + av_log(avctx, AV_LOG_ERROR, "packet of size %d too small\n", avpkt->size); + return AVERROR_INVALIDDATA; + } + ret = avctx->get_buffer(avctx, &s->frame); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -215,6 +225,10 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size, s->low_nibble = NULL; is_odd_frame = avpkt->data[0]; + if(is_odd_frame>1){ + av_log(avctx, AV_LOG_ERROR, "frame is too odd %d\n", is_odd_frame); + return AVERROR_INVALIDDATA; + } firstcolor = s->first_color[is_odd_frame]; palette = (uint32_t *)s->frame.data[1]; diff --git a/libavdevice/alsa-audio-common.c b/libavdevice/alsa-audio-common.c index 38466a06ce..7987872221 100644 --- a/libavdevice/alsa-audio-common.c +++ b/libavdevice/alsa-audio-common.c @@ -245,6 +245,7 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, } snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); + buffer_size = FFMIN(buffer_size, ALSA_BUFFER_SIZE_MAX); /* TODO: maybe use ctx->max_picture_buffer somehow */ res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size); if (res < 0) { @@ -254,6 +255,8 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, } snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL); + if (!period_size) + period_size = buffer_size / 4; res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size, NULL); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set ALSA period size (%s)\n", diff --git a/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h index 431401bb13..ac33d43ba2 100644 --- a/libavdevice/alsa-audio.h +++ b/libavdevice/alsa-audio.h @@ -42,6 +42,8 @@ typedef void (*ff_reorder_func)(const void *, void *, int); +#define ALSA_BUFFER_SIZE_MAX 65536 + typedef struct { AVClass *class; snd_pcm_t *h; diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index e49e5b71f7..0661bcbc2c 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -22,9 +22,9 @@ #include "libavutil/avutil.h" #include "libavformat/avformat.h" -#define LIBAVDEVICE_VERSION_MAJOR 53 -#define LIBAVDEVICE_VERSION_MINOR 1 -#define LIBAVDEVICE_VERSION_MICRO 1 +#define LIBAVDEVICE_VERSION_MAJOR 52 +#define LIBAVDEVICE_VERSION_MINOR 5 +#define LIBAVDEVICE_VERSION_MICRO 0 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 7223654891..163a4cdc03 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -439,7 +439,7 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) struct v4l2_streamparm streamparm = {0}; struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe; int i, ret; - AVRational fps; + AVRational fps={0}; streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c index a8e67e7dda..ea86c9a755 100644 --- a/libavdevice/vfwcap.c +++ b/libavdevice/vfwcap.c @@ -242,7 +242,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) AVStream *st; int devnum; int bisize; - BITMAPINFO *bi; + BITMAPINFO *bi = NULL; CAPTUREPARMS cparms; DWORD biCompression; WORD biBitCount; @@ -293,7 +293,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) (LPARAM) videostream_cb); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not set video stream callback.\n"); - goto fail_io; + goto fail; } SetWindowLongPtr(ctx->hwnd, GWLP_USERDATA, (LONG_PTR) s); @@ -307,7 +307,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) /* Set video format */ bisize = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, 0, 0); if(!bisize) - goto fail_io; + goto fail; bi = av_malloc(bisize); if(!bi) { vfw_read_close(s); @@ -315,7 +315,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) } ret = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, bisize, (LPARAM) bi); if(!ret) - goto fail_bi; + goto fail; dump_bih(s, &bi->bmiHeader); @@ -324,7 +324,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) ret = av_parse_video_size(&bi->bmiHeader.biWidth, &bi->bmiHeader.biHeight, ctx->video_size); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Couldn't parse video size.\n"); - goto fail_bi; + goto fail; } } #if FF_API_FORMAT_PARAMETERS @@ -349,19 +349,17 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) ret = SendMessage(ctx->hwnd, WM_CAP_SET_VIDEOFORMAT, bisize, (LPARAM) bi); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not set Video Format.\n"); - goto fail_bi; + goto fail; } biCompression = bi->bmiHeader.biCompression; biBitCount = bi->bmiHeader.biBitCount; - av_free(bi); - /* Set sequence setup */ ret = SendMessage(ctx->hwnd, WM_CAP_GET_SEQUENCE_SETUP, sizeof(cparms), (LPARAM) &cparms); if(!ret) - goto fail_io; + goto fail; dump_captureparms(s, &cparms); @@ -376,7 +374,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) ret = SendMessage(ctx->hwnd, WM_CAP_SET_SEQUENCE_SETUP, sizeof(cparms), (LPARAM) &cparms); if(!ret) - goto fail_io; + goto fail; codec = st->codec; codec->time_base = (AVRational){fps.den, fps.num}; @@ -405,31 +403,31 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) } } + av_freep(&bi); + av_set_pts_info(st, 32, 1, 1000); ctx->mutex = CreateMutex(NULL, 0, NULL); if(!ctx->mutex) { av_log(s, AV_LOG_ERROR, "Could not create Mutex.\n" ); - goto fail_io; + goto fail; } ctx->event = CreateEvent(NULL, 1, 0, NULL); if(!ctx->event) { av_log(s, AV_LOG_ERROR, "Could not create Event.\n" ); - goto fail_io; + goto fail; } ret = SendMessage(ctx->hwnd, WM_CAP_SEQUENCE_NOFILE, 0, 0); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not start capture sequence.\n" ); - goto fail_io; + goto fail; } return 0; -fail_bi: - av_free(bi); - -fail_io: +fail: + av_freep(&bi); vfw_read_close(s); return AVERROR(EIO); } diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index a57677c0e4..d2b4986cef 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -614,7 +614,7 @@ void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate; /* Copy actual data into new samples buffer */ - for (i = 0; samplesref->data[i]; i++) + for (i = 0; samplesref->data[i] && i < 8; i++) memcpy(link->cur_buf->data[i], samplesref->data[i], samplesref->linesize[0]); avfilter_unref_buffer(samplesref); diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index c276f3037e..1e6a08b1d8 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -25,8 +25,8 @@ #include "libavutil/avutil.h" #include "libavutil/samplefmt.h" -#define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 23 +#define LIBAVFILTER_VERSION_MAJOR 1 +#define LIBAVFILTER_VERSION_MINOR 80 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 04768617de..10f5fa856c 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -23,6 +23,7 @@ #include #include +#include "libavutil/avstring.h" #include "avfilter.h" #include "avfiltergraph.h" #include "internal.h" @@ -163,7 +164,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) /* couldn't merge format lists. auto-insert scale filter */ snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d", scaler_count++); - snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts); + 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(&scale, avfilter_get_by_name("scale"), inst_name, scale_args, NULL, graph)) < 0) return ret; diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 49977c51fd..8109872ad9 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -45,7 +45,11 @@ AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b) AVFilterFormats *ret; unsigned i, j, k = 0; - if (a == b) return a; + if (a == b) + return a; + + if (a == b) + return a; ret = av_mallocz(sizeof(AVFilterFormats)); diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index 5178eea4c6..1cc8285ad6 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -121,7 +121,8 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind return ret; } - if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags")) { + if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") && + ctx->scale_sws_opts) { snprintf(tmp_args, sizeof(tmp_args), "%s:%s", args, ctx->scale_sws_opts); args = tmp_args; diff --git a/libavfilter/libmpcodecs/vf_remove_logo.c b/libavfilter/libmpcodecs/vf_remove_logo.c index 5f1265eab3..5498a1bd03 100644 --- a/libavfilter/libmpcodecs/vf_remove_logo.c +++ b/libavfilter/libmpcodecs/vf_remove_logo.c @@ -671,7 +671,7 @@ static pgm_structure * generate_half_size_image(vf_instance_t * vf, pgm_structur * \brief Checks if YV12 is supported by the next filter. */ static unsigned int find_best(struct vf_instance *vf){ - int is_format_okay = vf->next->query_format(vf->next, IMGFMT_YV12); + int is_format_okay = vf_next_query_format(vf, IMGFMT_YV12); if ((is_format_okay & VFCAP_CSP_SUPPORTED_BY_HW) || (is_format_okay & VFCAP_CSP_SUPPORTED)) return IMGFMT_YV12; else @@ -814,7 +814,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ static int query_format(struct vf_instance *vf, unsigned int fmt) { if (fmt == IMGFMT_YV12) - return vf->next->query_format(vf->next, IMGFMT_YV12); + return vf_next_query_format(vf, IMGFMT_YV12); else return 0; } diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index e1b51c52c2..69a2cbc291 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -158,7 +158,7 @@ static int read_shape_from_file(int *cols, int *rows, int **values, const char * } w++; } - if (*rows > (SIZE_MAX / sizeof(int) / *cols)) { + if (*rows > (FF_INTERNAL_MEM_TYPE_MAX_VALUE / (sizeof(int)) / *cols)) { av_log(log_ctx, AV_LOG_ERROR, "File with size %dx%d is too big\n", *rows, *cols); return AVERROR_INVALIDDATA; diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index c457972474..c72e6374df 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -345,8 +345,8 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) #define DEFINE_LUT_FILTER(name_, description_, init_) \ AVFilter avfilter_vf_##name_ = { \ - .name = NULL_IF_CONFIG_SMALL(#name_), \ - .description = description_, \ + .name = #name_, \ + .description = NULL_IF_CONFIG_SMALL(description_), \ .priv_size = sizeof(LutContext), \ \ .init = init_, \ diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c index 36616b9c94..9e413b4776 100644 --- a/libavfilter/vf_mp.c +++ b/libavfilter/vf_mp.c @@ -41,6 +41,7 @@ //FIXME maybe link the orig in +//XXX: identical pix_fmt must be following with each others static const struct { int fmt; enum PixelFormat pix_fmt; @@ -785,13 +786,17 @@ static int query_formats(AVFilterContext *ctx) { AVFilterFormats *avfmts=NULL; MPContext *m = ctx->priv; + enum PixelFormat lastpixfmt = PIX_FMT_NONE; int i; for(i=0; conversion_map[i].fmt; i++){ av_log(ctx, AV_LOG_DEBUG, "query: %X\n", conversion_map[i].fmt); if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){ av_log(ctx, AV_LOG_DEBUG, "supported,adding\n"); - avfilter_add_format(&avfmts, conversion_map[i].pix_fmt); + if (conversion_map[i].pix_fmt != lastpixfmt) { + avfilter_add_format(&avfmts, conversion_map[i].pix_fmt); + lastpixfmt = conversion_map[i].pix_fmt; + } } } diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 0ca5bd08fc..1e5c042cb9 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -157,7 +157,7 @@ static int config_input(AVFilterLink *inlink) var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; var_values[VAR_A] = (float) inlink->w / inlink->h; var_values[VAR_HSUB] = 1<hsub; - var_values[VAR_VSUB] = 2<vsub; + var_values[VAR_VSUB] = 1<vsub; /* evaluate width and height */ av_expr_parse_and_eval(&res, (expr = pad->w_expr), @@ -299,6 +299,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { PadContext *pad = inlink->dst->priv; AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); + AVFilterBufferRef *for_next_filter; int plane; for (plane = 0; plane < 4 && outpicref->data[plane]; plane++) { @@ -335,12 +336,14 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref->video->w = pad->w; outpicref->video->h = pad->h; - avfilter_start_frame(inlink->dst->outputs[0], outpicref); + for_next_filter = avfilter_ref_buffer(outpicref, ~0); + avfilter_start_frame(inlink->dst->outputs[0], for_next_filter); } static void end_frame(AVFilterLink *link) { avfilter_end_frame(link->dst->outputs[0]); + avfilter_unref_buffer(link->dst->outputs[0]->out_buf); avfilter_unref_buffer(link->cur_buf); } diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index e172a2e586..1760233ff9 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -229,9 +229,16 @@ static int config_props(AVFilterLink *outlink) scale->isws[1] = sws_getContext(inlink ->w, inlink ->h/2, inlink ->format, outlink->w, outlink->h/2, outlink->format, scale->flags, NULL, NULL, NULL); - if (!scale->sws) + if (!scale->sws || !scale->isws[0] || !scale->isws[1]) return AVERROR(EINVAL); + if (inlink->sample_aspect_ratio.num) + outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w, + outlink->w*inlink->h}, + inlink->sample_aspect_ratio); + else + outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + return 0; fail: diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index 8b11ae8d53..64e1ab5e3e 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -69,16 +69,13 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_BGR555BE, PIX_FMT_BGR555LE, PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE, PIX_FMT_YUV420P16LE, PIX_FMT_YUV420P16BE, - PIX_FMT_YUV422P16LE, PIX_FMT_YUV422P16BE, PIX_FMT_YUV444P16LE, PIX_FMT_YUV444P16BE, PIX_FMT_NV12, PIX_FMT_NV21, PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, - PIX_FMT_YUV444P, PIX_FMT_YUV422P, + PIX_FMT_YUV444P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P, PIX_FMT_YUVJ420P, - PIX_FMT_YUV411P, PIX_FMT_YUV410P, - PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, - PIX_FMT_YUV440P, PIX_FMT_YUVJ440P, + PIX_FMT_YUV410P, PIX_FMT_YUVA420P, PIX_FMT_GRAY8, PIX_FMT_NONE }; @@ -195,6 +192,8 @@ static void end_frame(AVFilterLink *inlink) avfilter_unref_buffer(outpic); } +static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } + AVFilter avfilter_vf_transpose = { .name = "transpose", .description = NULL_IF_CONFIG_SMALL("Transpose input video."), @@ -207,6 +206,7 @@ AVFilter avfilter_vf_transpose = { .inputs = (AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .start_frame = start_frame, + .draw_slice = null_draw_slice, .end_frame = end_frame, .min_perms = AV_PERM_READ, }, { .name = NULL}}, diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 3542ca3eac..3a58a480b9 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -70,6 +70,7 @@ static void unsharpen(uint8_t *dst, const uint8_t *src, int dst_stride, int src_ int32_t res; int x, y, z; + const uint8_t *src2; if (!fp->amount) { if (dst_stride == src_stride) @@ -84,9 +85,12 @@ static void unsharpen(uint8_t *dst, const uint8_t *src, int dst_stride, int src_ memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * fp->steps_x)); for (y = -fp->steps_y; y < height + fp->steps_y; y++) { + if (y < height) + src2 = src; + memset(sr, 0, sizeof(sr[0]) * (2 * fp->steps_x - 1)); for (x = -fp->steps_x; x < width + fp->steps_x; x++) { - tmp1 = x <= 0 ? src[0] : x >= width ? src[width-1] : src[x]; + tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x]; for (z = 0; z < fp->steps_x * 2; z += 2) { tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1; tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2; @@ -125,8 +129,8 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) { UnsharpContext *unsharp = ctx->priv; - int lmsize_x = 5, cmsize_x = 0; - int lmsize_y = 5, cmsize_y = 0; + int lmsize_x = 5, cmsize_x = 5; + int lmsize_y = 5, cmsize_y = 5; double lamount = 1.0f, camount = 0.0f; if (args) diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 296328b71a..431d11b9de 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -36,8 +36,8 @@ typedef struct { int mode; /** - * 0: bottom field first - * 1: top field first + * 0: top field first + * 1: bottom field first * -1: auto-detection */ int parity; @@ -195,9 +195,12 @@ static void return_frame(AVFilterContext *ctx, int is_second) tff = yadif->parity^1; } - if (is_second) + if (is_second) { yadif->out = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE, link->w, link->h); + avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); + yadif->out->video->interlaced = 0; + } if (!yadif->csp) yadif->csp = &av_pix_fmt_descriptors[link->format]; diff --git a/libavfilter/x86/gradfun.c b/libavfilter/x86/gradfun.c index 05d4a6fd6e..e892117d67 100644 --- a/libavfilter/x86/gradfun.c +++ b/libavfilter/x86/gradfun.c @@ -1,19 +1,21 @@ /* + * Copyright (C) 2009 Loren Merritt + * * This file is part of FFmpeg. * - * FFmpeg is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with FFmpeg; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/cpu.h" diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 0b79c761a5..755a21168c 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -172,13 +172,16 @@ static int fourxm_read_header(AVFormatContext *s, goto fail; } if (current_track + 1 > fourxm->track_count) { - fourxm->track_count = current_track + 1; - fourxm->tracks = av_realloc(fourxm->tracks, - fourxm->track_count * sizeof(AudioTrack)); + fourxm->tracks = av_realloc_f(fourxm->tracks, + sizeof(AudioTrack), + current_track + 1); if (!fourxm->tracks) { - ret= AVERROR(ENOMEM); + 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]); @@ -192,6 +195,11 @@ static int fourxm_read_header(AVFormatContext *s, ret= -1; goto fail; } + if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){ + av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } i += 8 + size; /* allocate a new AVStream */ diff --git a/libavformat/Makefile b/libavformat/Makefile index e5ec44bfb6..7f24959883 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -10,6 +10,7 @@ OBJS = allformats.o \ id3v1.o \ id3v2.o \ metadata.o \ + metadata_compat.o \ options.o \ os_support.o \ sdp.o \ @@ -247,6 +248,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ rtpdec.o \ rtpdec_amr.o \ rtpdec_asf.o \ + rtpdec_g726.o \ rtpdec_h263.o \ rtpdec_h264.o \ rtpdec_latm.o \ diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c index fcf99363ee..92e468da43 100644 --- a/libavformat/ac3dec.c +++ b/libavformat/ac3dec.c @@ -40,6 +40,8 @@ static int ac3_eac3_probe(AVProbeData *p, enum CodecID expected_codec_id) buf2 = buf; for(frames = 0; buf2 < end; frames++) { + if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8)) + buf2+=16; init_get_bits(&gbc, buf2, 54); if(ff_ac3_parse_header(&gbc, &hdr) < 0) break; diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c index a03e128d96..43e719b5ea 100644 --- a/libavformat/adtsenc.c +++ b/libavformat/adtsenc.c @@ -59,6 +59,10 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf av_log(s, AV_LOG_ERROR, "Scalable configurations are not allowed in ADTS\n"); return -1; } + if (get_bits(&gb, 1)) { + av_log(s, AV_LOG_ERROR, "Extension flag is not allowed in ADTS\n"); + return -1; + } if (!adts->channel_conf) { init_put_bits(&pb, adts->pce_data, MAX_PCE_SIZE); diff --git a/libavformat/anm.c b/libavformat/anm.c index 269e325e42..1210e67dc7 100644 --- a/libavformat/anm.c +++ b/libavformat/anm.c @@ -134,18 +134,17 @@ static int read_header(AVFormatContext *s, /* color cycling and palette data */ st->codec->extradata_size = 16*8 + 4*256; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - ret = AVERROR(ENOMEM); - goto close_and_return; - } + if (!st->codec->extradata) + return AVERROR(ENOMEM); + ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size); if (ret < 0) - goto close_and_return; + return ret; /* read page table */ ret = avio_seek(pb, anm->page_table_offset, SEEK_SET); if (ret < 0) - goto close_and_return; + return ret; for (i = 0; i < MAX_PAGES; i++) { Page *p = &anm->pt[i]; @@ -156,21 +155,15 @@ static int read_header(AVFormatContext *s, /* find page of first frame */ anm->page = find_record(anm, 0); - if (anm->page < 0) { - ret = anm->page; - goto close_and_return; - } + if (anm->page < 0) + return anm->page; anm->record = -1; return 0; invalid: av_log_ask_for_sample(s, NULL); - ret = AVERROR_INVALIDDATA; - -close_and_return: - av_close_input_stream(s); - return ret; + return AVERROR_INVALIDDATA; } static int read_packet(AVFormatContext *s, diff --git a/libavformat/ape.c b/libavformat/ape.c index bda6b32b1d..7e18a403c3 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -270,8 +270,13 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) if (ape->seektablelength > 0) { ape->seektable = av_malloc(ape->seektablelength); + if (!ape->seektable) + return AVERROR(ENOMEM); for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) ape->seektable[i] = avio_rl32(pb); + }else{ + av_log(s, AV_LOG_ERROR, "Missing seektable\n"); + return -1; } ape->frames[0].pos = ape->firstframe; diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index ddf97e9d31..7c5ebc7f88 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -208,7 +208,7 @@ static int parse_playlist(AppleHTTPContext *c, const char *url, if (!in) { close_in = 1; - if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0) + if ((ret = avio_open(&in, url, AVIO_RDONLY)) < 0) return ret; } @@ -321,13 +321,13 @@ static int open_input(struct variant *var) { struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no]; if (seg->key_type == KEY_NONE) { - return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ); + return ffurl_open(&var->input, seg->url, AVIO_RDONLY); } else if (seg->key_type == KEY_AES_128) { char iv[33], key[33], url[MAX_URL_SIZE]; int ret; if (strcmp(seg->key, var->key_url)) { URLContext *uc; - if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) { + if (ffurl_open(&uc, seg->key, AVIO_RDONLY) == 0) { if (ffurl_read_complete(uc, var->key, sizeof(var->key)) != sizeof(var->key)) { av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n", @@ -347,7 +347,7 @@ static int open_input(struct variant *var) snprintf(url, sizeof(url), "crypto+%s", seg->url); else snprintf(url, sizeof(url), "crypto:%s", seg->url); - if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0) + if ((ret = ffurl_alloc(&var->input, url, AVIO_RDONLY)) < 0) return ret; av_set_string3(var->input->priv_data, "key", key, 0, NULL); av_set_string3(var->input->priv_data, "iv", iv, 0, NULL); @@ -395,7 +395,9 @@ reload: goto reload; } - ret = open_input(v); + ret = ffurl_open(&v->input, + v->segments[v->cur_seq_no - v->start_seq_no]->url, + AVIO_RDONLY); if (ret < 0) return ret; } diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c index bb5029d82f..e0bc6077c5 100644 --- a/libavformat/applehttpproto.c +++ b/libavformat/applehttpproto.c @@ -114,7 +114,7 @@ static int parse_playlist(URLContext *h, const char *url) char line[1024]; const char *ptr; - if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0) + if ((ret = avio_open(&in, url, AVIO_RDONLY)) < 0) return ret; read_chomp_line(in, line, sizeof(line)); @@ -179,7 +179,7 @@ static int applehttp_open(URLContext *h, const char *uri, int flags) int ret, i; const char *nested_url; - if (flags & AVIO_FLAG_WRITE) + if (flags & (AVIO_WRONLY | AVIO_RDWR)) return AVERROR(ENOSYS); s = av_mallocz(sizeof(AppleHTTPContext)); @@ -194,7 +194,7 @@ static int applehttp_open(URLContext *h, const char *uri, int flags) av_strlcpy(s->playlisturl, "http://", sizeof(s->playlisturl)); av_strlcat(s->playlisturl, nested_url, sizeof(s->playlisturl)); } else { - av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri); + av_log(NULL, AV_LOG_ERROR, "Unsupported url %s\n", uri); ret = AVERROR(EINVAL); goto fail; } @@ -217,7 +217,7 @@ static int applehttp_open(URLContext *h, const char *uri, int flags) } if (s->n_segments == 0) { - av_log(h, AV_LOG_WARNING, "Empty playlist\n"); + av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); ret = AVERROR(EIO); goto fail; } @@ -257,7 +257,7 @@ retry: return ret; } if (s->cur_seq_no < s->start_seq_no) { - av_log(h, AV_LOG_WARNING, + av_log(NULL, AV_LOG_WARNING, "skipping %d segments ahead, expired from playlist\n", s->start_seq_no - s->cur_seq_no); s->cur_seq_no = s->start_seq_no; @@ -273,12 +273,12 @@ retry: goto retry; } url = s->segments[s->cur_seq_no - s->start_seq_no]->url, - av_log(h, AV_LOG_DEBUG, "opening %s\n", url); - ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ); + av_log(NULL, AV_LOG_DEBUG, "opening %s\n", url); + ret = ffurl_open(&s->seg_hd, url, AVIO_RDONLY); if (ret < 0) { if (url_interrupt_cb()) return AVERROR_EXIT; - av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url); + av_log(NULL, AV_LOG_WARNING, "Unable to open %s\n", url); s->cur_seq_no++; goto retry; } diff --git a/libavformat/asf.h b/libavformat/asf.h index 3f6783bf5a..c3107f4a0c 100644 --- a/libavformat/asf.h +++ b/libavformat/asf.h @@ -45,8 +45,6 @@ typedef struct { uint16_t stream_language_index; - int palette_changed; - uint32_t palette[256]; } ASFStream; typedef struct { diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index db00964c8a..ad6b8a3055 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -196,6 +196,8 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size) asf->hdr.flags = avio_rl32(pb); asf->hdr.min_pktsize = avio_rl32(pb); asf->hdr.max_pktsize = avio_rl32(pb); + if (asf->hdr.min_pktsize >= (1U<<29)) + return AVERROR_INVALIDDATA; asf->hdr.max_bitrate = avio_rl32(pb); s->packet_size = asf->hdr.max_pktsize; @@ -359,14 +361,15 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) /* This is true for all paletted codecs implemented in ffmpeg */ if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { int av_unused i; + st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); #if HAVE_BIGENDIAN for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) - asf_st->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); + st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); #else - memcpy(asf_st->palette, st->codec->extradata, - FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); + memcpy(st->codec->palctrl->palette, st->codec->extradata, + FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); #endif - asf_st->palette_changed = 1; + st->codec->palctrl->palette_changed = 1; } st->codec->codec_tag = tag1; @@ -609,7 +612,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (gsize < 24) return -1; if (!ff_guidcmp(&g, &ff_asf_file_header)) { - asf_read_file_properties(s, gsize); + int ret = asf_read_file_properties(s, gsize); + if (ret < 0) + return ret; } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) { asf_read_stream_properties(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) { @@ -750,7 +755,7 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) c= avio_r8(pb); d= avio_r8(pb); rsize+=3; - }else{ + } else if (!pb->eof_reached) { avio_seek(pb, -1, SEEK_CUR); //FIXME } @@ -782,6 +787,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) asf->packet_segments = 1; asf->packet_segsizetype = 0x80; } + if (rsize > packet_length - padsize) { + asf->packet_size_left = 0; + av_log(s, AV_LOG_ERROR, + "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n", + rsize, packet_length, padsize, avio_tell(pb)); + return -1; + } asf->packet_size_left = packet_length - padsize - rsize; if (packet_length < asf->hdr.min_pktsize) padsize += asf->hdr.min_pktsize - packet_length; @@ -808,6 +820,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){ DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); DO_2BITS(asf->packet_property, asf->packet_replic_size, 0); //printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size); + if (rsize+asf->packet_replic_size > asf->packet_size_left) { + av_log(s, AV_LOG_ERROR, "packet_replic_size %d is invalid\n", asf->packet_replic_size); + return -1; + } if (asf->packet_replic_size >= 8) { asf->packet_obj_size = avio_rl32(pb); if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){ @@ -842,10 +858,6 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){ av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size); return -1; } - if (rsize > asf->packet_size_left) { - av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n"); - return -1; - } if (asf->packet_flags & 0x01) { DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal if (rsize > asf->packet_size_left) { @@ -970,17 +982,6 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->pkt.stream_index = asf->stream_index; asf_st->pkt.pos = asf_st->packet_pos= asf->packet_pos; - if (asf_st->pkt.data && asf_st->palette_changed) { - uint8_t *pal; - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, - AVPALETTE_SIZE); - if (!pal) { - av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n"); - } else { - memcpy(pal, asf_st->palette, AVPALETTE_SIZE); - asf_st->palette_changed = 0; - } - } //printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", //asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & AV_PKT_FLAG_KEY, //s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO, asf->packet_obj_size); @@ -1137,8 +1138,14 @@ static void asf_reset_header(AVFormatContext *s) static int asf_read_close(AVFormatContext *s) { + int i; asf_reset_header(s); + for(i=0;inb_streams;i++) { + AVStream *st = s->streams[i]; + av_free(st->codec->palctrl); + } + return 0; } @@ -1158,7 +1165,8 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, if (s->packet_size > 0) pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset; *ppos= pos; - avio_seek(s->pb, pos, SEEK_SET); + if (avio_seek(s->pb, pos, SEEK_SET) < 0) + return AV_NOPTS_VALUE; //printf("asf_read_pts\n"); asf_reset_header(s); @@ -1200,7 +1208,9 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index) int64_t current_pos= avio_tell(s->pb); int i; - avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET); + if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) + return; + ff_get_guid(s->pb, &g); /* the data object can be followed by other top-level objects, @@ -1272,7 +1282,8 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int /* do the seek */ av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos); - avio_seek(s->pb, pos, SEEK_SET); + if(avio_seek(s->pb, pos, SEEK_SET) < 0) + return -1; asf_reset_header(s); return 0; } diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 1734649a95..2587629723 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -48,63 +48,70 @@ const char *avformat_license(void); struct AVFormatContext; -/* - * Public Metadata API. +/** + * @defgroup metadata_api Public Metadata API + * @{ * The metadata API allows libavformat to export metadata tags to a client * application using a sequence of key/value pairs. Like all strings in FFmpeg, * metadata must be stored as UTF-8 encoded Unicode. Note that metadata * exported by demuxers isn't checked to be valid UTF-8 in most cases. * Important concepts to keep in mind: - * 1. Keys are unique; there can never be 2 tags with the same key. This is + * - Keys are unique; there can never be 2 tags with the same key. This is * also meant semantically, i.e., a demuxer should not knowingly produce * several keys that are literally different but semantically identical. * E.g., key=Author5, key=Author6. In this example, all authors must be * placed in the same tag. - * 2. Metadata is flat, not hierarchical; there are no subtags. If you + * - Metadata is flat, not hierarchical; there are no subtags. If you * want to store, e.g., the email address of the child of producer Alice * and actor Bob, that could have key=alice_and_bobs_childs_email_address. - * 3. Several modifiers can be applied to the tag name. This is done by + * - Several modifiers can be applied to the tag name. This is done by * appending a dash character ('-') and the modifier name in the order * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. - * a) language -- a tag whose value is localized for a particular language + * - language -- a tag whose value is localized for a particular language * is appended with the ISO 639-2/B 3-letter language code. * For example: Author-ger=Michael, Author-eng=Mike * The original/default language is in the unqualified "Author" tag. * A demuxer should set a default if it sets any translated tag. - * b) sorting -- a modified version of a tag that should be used for + * - sorting -- a modified version of a tag that should be used for * sorting will have '-sort' appended. E.g. artist="The Beatles", * artist-sort="Beatles, The". * - * 4. Demuxers attempt to export metadata in a generic format, however tags + * - Demuxers attempt to export metadata in a generic format, however tags * with no generic equivalents are left as they are stored in the container. * Follows a list of generic tag names: * - * album -- name of the set this work belongs to - * album_artist -- main creator of the set/album, if different from artist. - * e.g. "Various Artists" for compilation albums. - * artist -- main creator of the work - * comment -- any additional description of the file. - * composer -- who composed the work, if different from artist. - * copyright -- name of copyright holder. - * creation_time-- date when the file was created, preferably in ISO 8601. - * date -- date when the work was created, preferably in ISO 8601. - * disc -- number of a subset, e.g. disc in a multi-disc collection. - * encoder -- name/settings of the software/hardware that produced the file. - * encoded_by -- person/group who created the file. - * filename -- original name of the file. - * genre -- . - * language -- main language in which the work is performed, preferably - * in ISO 639-2 format. Multiple languages can be specified by - * separating them with commas. - * performer -- artist who performed the work, if different from artist. - * E.g for "Also sprach Zarathustra", artist would be "Richard - * Strauss" and performer "London Philharmonic Orchestra". - * publisher -- name of the label/publisher. - * service_name -- name of the service in broadcasting (channel name). - * service_provider -- name of the service provider in broadcasting. - * title -- name of the work. - * track -- number of this work in the set, can be in form current/total. - * variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of + @verbatim + album -- name of the set this work belongs to + album_artist -- main creator of the set/album, if different from artist. + e.g. "Various Artists" for compilation albums. + artist -- main creator of the work + comment -- any additional description of the file. + composer -- who composed the work, if different from artist. + copyright -- name of copyright holder. + creation_time-- date when the file was created, preferably in ISO 8601. + date -- date when the work was created, preferably in ISO 8601. + disc -- number of a subset, e.g. disc in a multi-disc collection. + encoder -- name/settings of the software/hardware that produced the file. + encoded_by -- person/group who created the file. + filename -- original name of the file. + genre -- . + language -- main language in which the work is performed, preferably + in ISO 639-2 format. Multiple languages can be specified by + separating them with commas. + performer -- artist who performed the work, if different from artist. + E.g for "Also sprach Zarathustra", artist would be "Richard + Strauss" and performer "London Philharmonic Orchestra". + publisher -- name of the label/publisher. + service_name -- name of the service in broadcasting (channel name). + service_provider -- name of the service provider in broadcasting. + title -- name of the work. + track -- number of this work in the set, can be in form current/total. + variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of + @endverbatim + * + * Look in the examples section for an application example how to use the Metadata API. + * + * @} */ #if FF_API_OLD_METADATA2 @@ -137,6 +144,20 @@ typedef struct AVMetadataConv AVMetadataConv; attribute_deprecated AVDictionaryEntry * av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags); +#if FF_API_OLD_METADATA +/** + * Set the given tag in *pm, overwriting an existing tag. + * + * @param pm pointer to a pointer to a metadata struct. If *pm is NULL + * a metadata struct is allocated and put in *pm. + * @param key tag key to add to *pm (will be av_strduped) + * @param value tag value to add to *pm (will be av_strduped) + * @return >= 0 on success otherwise an error code <0 + * @deprecated Use av_metadata_set2() instead. + */ +attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const char *value); +#endif + /** * Set the given tag in *pm, overwriting an existing tag. * @@ -249,6 +270,10 @@ typedef struct AVFormatParameters { immediately (RTSP only). */ attribute_deprecated unsigned int prealloced_context:1; #endif +#if FF_API_PARAMETERS_CODEC_ID + attribute_deprecated enum CodecID video_codec_id; + attribute_deprecated enum CodecID audio_codec_id; +#endif } AVFormatParameters; //! Demuxer will use avio_open, no opened file should be provided by the caller. @@ -541,6 +566,10 @@ typedef struct AVStream { */ int64_t duration; +#if FF_API_OLD_METADATA + attribute_deprecated char language[4]; /**< ISO 639-2/B 3-letter language code (empty string if undefined) */ +#endif + /* av_read_frame() support */ enum AVStreamParseType need_parsing; struct AVCodecParserContext *parser; @@ -556,6 +585,14 @@ typedef struct AVStream { int64_t nb_frames; ///< number of frames in this stream if known or 0 +#if FF_API_LAVF_UNUSED + attribute_deprecated int64_t unused[4+1]; +#endif + +#if FF_API_OLD_METADATA + attribute_deprecated char *filename; /**< source filename of the stream */ +#endif + int disposition; /**< AV_DISPOSITION_* bit field */ AVProbeData probe_data; @@ -646,6 +683,10 @@ typedef struct AVStream { */ typedef struct AVProgram { int id; +#if FF_API_OLD_METADATA + attribute_deprecated char *provider_name; ///< network name for DVB streams + attribute_deprecated char *name; ///< service name for DVB streams +#endif int flags; enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller unsigned int *stream_index; @@ -664,9 +705,16 @@ typedef struct AVChapter { int id; ///< unique ID to identify the chapter AVRational time_base; ///< time base in which the start/end timestamps are specified int64_t start, end; ///< chapter start/end time in time_base units +#if FF_API_OLD_METADATA + attribute_deprecated char *title; ///< chapter title +#endif AVDictionary *metadata; } AVChapter; +#if FF_API_MAX_STREAMS +#define MAX_STREAMS 20 +#endif + /** * Format I/O context. * New fields can be added to the end with minor version bumps. @@ -682,10 +730,24 @@ typedef struct AVFormatContext { void *priv_data; AVIOContext *pb; unsigned int nb_streams; +#if FF_API_MAX_STREAMS + AVStream *streams[MAX_STREAMS]; +#else AVStream **streams; +#endif char filename[1024]; /**< input or output filename */ /* stream info */ int64_t timestamp; +#if FF_API_OLD_METADATA + attribute_deprecated char title[512]; + attribute_deprecated char author[512]; + attribute_deprecated char copyright[512]; + attribute_deprecated char comment[512]; + attribute_deprecated char album[512]; + attribute_deprecated int year; /**< ID3 year, 0 if none */ + attribute_deprecated int track; /**< track number, 0 if none */ + attribute_deprecated char genre[32]; /**< ID3 genre */ +#endif int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ /* private data for pts handling (do not modify directly). */ @@ -725,9 +787,17 @@ typedef struct AVFormatContext { /* av_read_frame() support */ AVStream *cur_st; +#if FF_API_LAVF_UNUSED + const uint8_t *cur_ptr_deprecated; + int cur_len_deprecated; + AVPacket cur_pkt_deprecated; +#endif /* av_seek_frame() support */ int64_t data_offset; /**< offset of the first packet */ +#if FF_API_INDEX_BUILT + attribute_deprecated int index_built; +#endif int mux_rate; unsigned int packet_size; @@ -867,6 +937,11 @@ typedef struct AVPacketList { struct AVPacketList *next; } AVPacketList; +#if FF_API_FIRST_FORMAT +attribute_deprecated extern AVInputFormat *first_iformat; +attribute_deprecated extern AVOutputFormat *first_oformat; +#endif + /** * If f is NULL, returns the first registered input format, * if f is non-NULL, returns the next registered input format after f @@ -891,6 +966,18 @@ attribute_deprecated enum CodecID av_guess_image2_codec(const char *filename); /* utils.c */ void av_register_input_format(AVInputFormat *format); void av_register_output_format(AVOutputFormat *format); +#if FF_API_GUESS_FORMAT +attribute_deprecated AVOutputFormat *guess_stream_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * @deprecated Use av_guess_format() instead. + */ +attribute_deprecated AVOutputFormat *guess_format(const char *short_name, + const char *filename, + const char *mime_type); +#endif /** * Return the output format in the list of registered output formats @@ -1107,6 +1194,12 @@ attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr, const char */ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options); +#if FF_API_ALLOC_FORMAT_CONTEXT +/** + * @deprecated Use avformat_alloc_context() instead. + */ +attribute_deprecated AVFormatContext *av_alloc_format_context(void); +#endif int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap); /** @@ -1145,6 +1238,7 @@ AVFormatContext *avformat_alloc_output_context(const char *format, int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename); +#if FF_API_FORMAT_PARAMETERS /** * Read packets of a media file to get stream information. This * is useful for file formats with no headers such as MPEG. This @@ -1157,8 +1251,34 @@ int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oforma * @return >=0 if OK, AVERROR_xxx on error * @todo Let the user decide somehow what information is needed so that * we do not waste time getting stuff the user does not need. + * + * @deprecated use avformat_find_stream_info. */ int av_find_stream_info(AVFormatContext *ic); +#endif + +/** + * Read packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real framerate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @param options If non-NULL, an ic.nb_streams long array of pointers to + * dictionaries, where i-th member contains options for + * codec corresponding to i-th stream. + * On return each dictionary will be filled with options that were not found. + * @return >=0 if OK, AVERROR_xxx on error + * + * @note this function isn't guaranteed to open all the codecs, so + * options being non-empty at return is a perfectly normal behavior. + * + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options); /** * Find the "best" stream in the file. @@ -1533,6 +1653,22 @@ void av_dump_format(AVFormatContext *ic, const char *url, int is_output); +#if FF_API_PARSE_FRAME_PARAM +/** + * Parse width and height out of string str. + * @deprecated Use av_parse_video_frame_size instead. + */ +attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, + const char *str); + +/** + * Convert framerate from a string to a fraction. + * @deprecated Use av_parse_video_frame_rate instead. + */ +attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, + const char *arg); +#endif + #if FF_API_PARSE_DATE /** * Parse datestr and return a corresponding number of microseconds. diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 80620dadba..1a1db244b5 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -220,13 +220,18 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ return -1; } - avio_seek(pb, offset+8, SEEK_SET); + if(avio_seek(pb, offset+8, SEEK_SET) < 0) + return -1; avi->odml_depth++; read_braindead_odml_indx(s, frame_num); avi->odml_depth--; frame_num += duration; - avio_seek(pb, pos, SEEK_SET); + if(avio_seek(pb, pos, SEEK_SET) < 0) { + av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index"); + return -1; + } + } } avi->index_loaded=1; @@ -606,18 +611,15 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) /* This code assumes that extradata contains only palette. */ /* This is true for all paletted codecs implemented in FFmpeg. */ if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { - int pal_size = (1 << st->codec->bits_per_coded_sample) << 2; - const uint8_t *pal_src; - - pal_size = FFMIN(pal_size, st->codec->extradata_size); - pal_src = st->codec->extradata + st->codec->extradata_size - pal_size; + st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); #if HAVE_BIGENDIAN - for (i = 0; i < pal_size/4; i++) - ast->pal[i] = AV_RL32(pal_src+4*i); + for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) + st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); #else - memcpy(ast->pal, pal_src, pal_size); + memcpy(st->codec->palctrl->palette, st->codec->extradata, + FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); #endif - ast->has_pal = 1; + st->codec->palctrl->palette_changed = 1; } print_tag("video", tag1, 0); @@ -634,7 +636,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){ st->codec->extradata_size+= 9; - st->codec->extradata= av_realloc(st->codec->extradata, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if(st->codec->extradata) memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9); } @@ -959,14 +961,14 @@ resync: return err; if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){ - uint8_t *pal; - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); - if(!pal){ - av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n"); - }else{ - memcpy(pal, ast->pal, AVPALETTE_SIZE); - ast->has_pal = 0; - } + void *ptr= av_realloc(pkt->data, pkt->size + 4*256 + FF_INPUT_BUFFER_PADDING_SIZE); + if(ptr){ + ast->has_pal=0; + pkt->size += 4*256; + pkt->data= ptr; + memcpy(pkt->data + pkt->size - 4*256, ast->pal, 4*256); + }else + av_log(s, AV_LOG_ERROR, "Failed to append palette\n"); } if (CONFIG_DV_DEMUXER && avi->dv_demux) { @@ -1026,7 +1028,7 @@ resync: } ast->frame_offset += get_duration(ast, pkt->size); } - ast->remaining -= size; + ast->remaining -= err; if(!ast->remaining){ avi->stream_index= -1; ast->packet_size= 0; @@ -1038,7 +1040,7 @@ resync: } ast->seek_pos= 0; - return size; + return 0; } memset(d, -1, sizeof(int)*8); @@ -1325,11 +1327,13 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp /* the av_index_search_timestamp call above. */ assert(stream_index == 0); + if(avio_seek(s->pb, pos, SEEK_SET) < 0) + return -1; + /* Feed the DV video stream version of the timestamp to the */ /* DV demux so it can synthesize correct timestamps. */ dv_offset_reset(avi->dv_demux, timestamp); - avio_seek(s->pb, pos, SEEK_SET); avi->stream_index= -1; return 0; } @@ -1380,7 +1384,8 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp } /* do the seek */ - avio_seek(s->pb, pos_min, SEEK_SET); + if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) + return -1; avi->stream_index= -1; return 0; } @@ -1393,6 +1398,7 @@ static int avi_read_close(AVFormatContext *s) for(i=0;inb_streams;i++) { AVStream *st = s->streams[i]; AVIStream *ast = st->priv_data; + av_free(st->codec->palctrl); if (ast) { if (ast->sub_ctx) { av_freep(&ast->sub_ctx->pb); diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 8a53bb53d3..1c8eedad09 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -523,6 +523,11 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){ AVPacket empty_packet; + if(pkt->dts - avist->packet_count > 60000){ + av_log(s, AV_LOG_ERROR, "Too large number of skiped frames %Ld\n", pkt->dts - avist->packet_count); + return AVERROR(EINVAL); + } + av_init_packet(&empty_packet); empty_packet.size= 0; empty_packet.data= NULL; @@ -558,7 +563,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE; int id = idx->entry % AVI_INDEX_CLUSTER_SIZE; if (idx->ents_allocated <= idx->entry) { - idx->cluster = av_realloc(idx->cluster, (cl+1)*sizeof(void*)); + idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1); if (!idx->cluster) return -1; idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry)); diff --git a/libavformat/avio.c b/libavformat/avio.c index b2926c0f3c..80644795d5 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -30,6 +30,7 @@ #endif #include "url.h" +#if FF_API_URL_CLASS /** @name Logging context. */ /*@{*/ static const char *urlcontext_to_name(void *ptr) @@ -46,6 +47,7 @@ static const AVClass urlcontext_class = { .version = LIBAVUTIL_VERSION_INT, }; /*@}*/ +#endif static int default_interrupt_cb(void); @@ -83,6 +85,29 @@ int ffurl_register_protocol(URLProtocol *protocol, int size) return 0; } +#if FF_API_REGISTER_PROTOCOL +/* The layout of URLProtocol as of when major was bumped to 52 */ +struct URLProtocol_compat { + const char *name; + int (*url_open)(URLContext *h, const char *filename, int flags); + int (*url_read)(URLContext *h, unsigned char *buf, int size); + int (*url_write)(URLContext *h, unsigned char *buf, int size); + int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); + int (*url_close)(URLContext *h); + struct URLProtocol *next; +}; + +int av_register_protocol(URLProtocol *protocol) +{ + return ffurl_register_protocol(protocol, sizeof(struct URLProtocol_compat)); +} + +int register_protocol(URLProtocol *protocol) +{ + return ffurl_register_protocol(protocol, sizeof(struct URLProtocol_compat)); +} +#endif + static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, const char *filename, int flags) { @@ -98,7 +123,9 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, err = AVERROR(ENOMEM); goto fail; } +#if FF_API_URL_CLASS uc->av_class = &urlcontext_class; +#endif uc->filename = (char *) &uc[1]; strcpy(uc->filename, filename); uc->prot = up; @@ -130,7 +157,7 @@ int ffurl_connect(URLContext* uc) return err; uc->is_connected = 1; //We must be careful here as ffurl_seek() could be slow, for example for http - if( (uc->flags & AVIO_FLAG_WRITE) + if( (uc->flags & (AVIO_WRONLY | AVIO_RDWR)) || !strcmp(uc->prot->name, "file")) if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0) uc->is_streamed= 1; @@ -290,21 +317,21 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int int ffurl_read(URLContext *h, unsigned char *buf, int size) { - if (!(h->flags & AVIO_FLAG_READ)) + if (h->flags & AVIO_WRONLY) return AVERROR(EIO); return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read); } int ffurl_read_complete(URLContext *h, unsigned char *buf, int size) { - if (!(h->flags & AVIO_FLAG_READ)) + if (h->flags & AVIO_WRONLY) return AVERROR(EIO); return retry_transfer_wrapper(h, buf, size, size, h->prot->url_read); } int ffurl_write(URLContext *h, const unsigned char *buf, int size) { - if (!(h->flags & AVIO_FLAG_WRITE)) + if (!(h->flags & (AVIO_WRONLY | AVIO_RDWR))) return AVERROR(EIO); /* avoid sending too big packets */ if (h->max_packet_size && size > h->max_packet_size) @@ -343,7 +370,7 @@ int ffurl_close(URLContext *h) int url_exist(const char *filename) { URLContext *h; - if (ffurl_open(&h, filename, AVIO_FLAG_READ) < 0) + if (ffurl_open(&h, filename, AVIO_RDONLY) < 0) return 0; ffurl_close(h); return 1; diff --git a/libavformat/avio.h b/libavformat/avio.h index bf1ea30bb3..fb04e431b7 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -101,7 +101,9 @@ typedef struct { * @deprecated This struct will be made private */ typedef struct URLContext { +#if FF_API_URL_CLASS const AVClass *av_class; ///< information for av_log(). Set by url_open(). +#endif struct URLProtocol *prot; int flags; int is_streamed; /**< true if streamed (no seek possible), default = false */ @@ -145,14 +147,14 @@ typedef struct URLPollEntry { attribute_deprecated int url_poll(URLPollEntry *poll_table, int n, int timeout); /** - * @defgroup open_modes URL open modes + * @name URL open modes * The flags argument to url_open and cosins must be one of the following * constants, optionally ORed with other flags. * @{ */ -#define URL_RDONLY 1 /**< read-only */ -#define URL_WRONLY 2 /**< write-only */ -#define URL_RDWR (URL_RDONLY|URL_WRONLY) /**< read-write */ +#define URL_RDONLY 0 /**< read-only */ +#define URL_WRONLY 1 /**< write-only */ +#define URL_RDWR 2 /**< read-write */ /** * @} */ @@ -176,7 +178,7 @@ extern URLInterruptCB *url_interrupt_cb; /** * @defgroup old_url_funcs Old url_* functions - * @deprecated use the buffered API based on AVIOContext instead + * The following functions are deprecated. Use the buffered API based on #AVIOContext instead. * @{ */ attribute_deprecated int url_open_protocol (URLContext **puc, struct URLProtocol *up, @@ -236,7 +238,7 @@ attribute_deprecated AVIOContext *av_alloc_put_byte( /** * @defgroup old_avio_funcs Old put_/get_*() functions - * @deprecated use the avio_ -prefixed functions instead. + * The following functions are deprecated. Use the "avio_"-prefixed functions instead. * @{ */ attribute_deprecated int get_buffer(AVIOContext *s, unsigned char *buf, int size); @@ -273,7 +275,7 @@ attribute_deprecated int64_t av_url_read_fseek (AVIOContext *h, int stream_in /** * @defgroup old_url_f_funcs Old url_f* functions - * @deprecated use the avio_ -prefixed functions instead. + * The following functions are deprecated, use the "avio_"-prefixed functions instead. * @{ */ attribute_deprecated int url_fopen( AVIOContext **s, const char *url, int flags); @@ -344,7 +346,7 @@ attribute_deprecated int url_exist(const char *url); #endif // FF_API_OLD_AVIO /** - * Return AVIO_FLAG_* access flags corresponding to the access permissions + * Return AVIO_* access flags corresponding to the access permissions * of the resource in url, or a negative value corresponding to an * AVERROR code in case of failure. The returned access flags are * masked by the value in flags. @@ -354,6 +356,9 @@ attribute_deprecated int url_exist(const char *url); * one call to another. Thus you should not trust the returned value, * unless you are sure that no other processes are accessing the * checked resource. + * + * @note This function is slightly broken until next major bump + * because of AVIO_RDONLY == 0. Don't use it until then. */ int avio_check(const char *url, int flags); @@ -365,6 +370,22 @@ int avio_check(const char *url, int flags); */ void avio_set_interrupt_cb(int (*interrupt_cb)(void)); +#if FF_API_REGISTER_PROTOCOL +extern URLProtocol *first_protocol; +#endif + +#if FF_API_REGISTER_PROTOCOL +/** + * @deprecated Use av_register_protocol() instead. + */ +attribute_deprecated int register_protocol(URLProtocol *protocol); + +/** + * @deprecated Use av_register_protocol2() instead. + */ +attribute_deprecated int av_register_protocol(URLProtocol *protocol); +#endif + /** * Allocate and initialize an AVIOContext for buffered I/O. It must be later * freed with av_free(). @@ -479,7 +500,7 @@ void avio_flush(AVIOContext *s); int avio_read(AVIOContext *s, unsigned char *buf, int size); /** - * @defgroup avio_read Functions for reading from AVIOContext. + * @name Functions for reading from AVIOContext * @{ * * @note return 0 if EOF, so you cannot use it if EOF handling is @@ -522,15 +543,29 @@ int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen); int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); +#if FF_API_URL_RESETBUF +/** Reset the buffer for reading or writing. + * @note Will drop any data currently in the buffer without transmitting it. + * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY + * to set up the buffer for writing. */ +int url_resetbuf(AVIOContext *s, int flags); +#endif + /** - * @defgroup open_modes URL open modes + * @name URL open modes * The flags argument to avio_open must be one of the following * constants, optionally ORed with other flags. * @{ */ -#define AVIO_FLAG_READ 1 /**< read-only */ -#define AVIO_FLAG_WRITE 2 /**< write-only */ -#define AVIO_FLAG_READ_WRITE (AVIO_FLAG_READ|AVIO_FLAG_WRITE) /**< read-write pseudo flag */ +#if LIBAVFORMAT_VERSION_MAJOR < 53 +#define AVIO_RDONLY 0 /**< read-only */ +#define AVIO_WRONLY 1 /**< write-only */ +#define AVIO_RDWR 2 /**< read-write */ +#else +#define AVIO_RDONLY 1 /**< read-only */ +#define AVIO_WRONLY 2 /**< write-only */ +#define AVIO_RDWR 4 /**< read-write */ +#endif /** * @} */ @@ -547,7 +582,11 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); * Warning: non-blocking protocols is work-in-progress; this flag may be * silently ignored. */ +#if LIBAVFORMAT_VERSION_MAJOR < 53 +#define AVIO_FLAG_NONBLOCK 4 +#else #define AVIO_FLAG_NONBLOCK 8 +#endif /** * Create and initialize a AVIOContext for accessing the @@ -591,6 +630,10 @@ int avio_open_dyn_buf(AVIOContext **s); */ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer); +#if FF_API_UDP_GET_FILE +int udp_get_file_handle(URLContext *h); +#endif + /** * Iterate through names of available protocols. * @note it is recommanded to use av_protocol_next() instead of this diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index aad0240d53..8c6be84017 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -38,7 +38,9 @@ #define SHORT_SEEK_THRESHOLD 4096 static void fill_buffer(AVIOContext *s); +#if !FF_API_URL_RESETBUF static int url_resetbuf(AVIOContext *s, int flags); +#endif int ffio_init_context(AVIOContext *s, unsigned char *buffer, @@ -53,7 +55,7 @@ int ffio_init_context(AVIOContext *s, s->buffer_size = buffer_size; s->buf_ptr = buffer; s->opaque = opaque; - url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ); + url_resetbuf(s, write_flag ? AVIO_WRONLY : AVIO_RDONLY); s->write_packet = write_packet; s->read_packet = read_packet; s->seek = seek; @@ -201,6 +203,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } + if (offset < 0) + return AVERROR(EINVAL); + offset1 = offset - pos; if (!s->must_flush && offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { @@ -778,13 +783,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) { int i; + if (buflen <= 0) + return AVERROR(EINVAL); // reserve 1 byte for terminating 0 buflen = FFMIN(buflen - 1, maxlen); for (i = 0; i < buflen; i++) if (!(buf[i] = avio_r8(s))) return i + 1; - if (buflen) - buf[i] = 0; + buf[i] = 0; for (; i < maxlen; i++) if (!avio_r8(s)) return i + 1; @@ -796,6 +802,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) {\ char* q = buf;\ int ret = 0;\ + if (buflen <= 0) \ + return AVERROR(EINVAL); \ while (ret + 1 < maxlen) {\ uint8_t tmp;\ uint32_t ch;\ @@ -854,7 +862,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) } if (ffio_init_context(*s, buffer, buffer_size, - h->flags & AVIO_FLAG_WRITE, h, + (h->flags & AVIO_WRONLY || h->flags & AVIO_RDWR), h, (void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek) < 0) { av_free(buffer); av_freep(s); @@ -883,15 +891,24 @@ int ffio_set_buf_size(AVIOContext *s, int buf_size) s->buffer = buffer; s->buffer_size = buf_size; s->buf_ptr = buffer; - url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ); + url_resetbuf(s, s->write_flag ? AVIO_WRONLY : AVIO_RDONLY); return 0; } +#if FF_API_URL_RESETBUF +int url_resetbuf(AVIOContext *s, int flags) +#else static int url_resetbuf(AVIOContext *s, int flags) +#endif { - assert(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ); +#if FF_API_URL_RESETBUF + if (flags & AVIO_RDWR) + return AVERROR(EINVAL); +#else + assert(flags == AVIO_WRONLY || flags == AVIO_RDONLY); +#endif - if (flags & AVIO_FLAG_WRITE) { + if (flags & AVIO_WRONLY) { s->buf_end = s->buffer + s->buffer_size; s->write_flag = 1; } else { @@ -921,7 +938,7 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size alloc_size = FFMAX(s->buffer_size, new_size); if (alloc_size > buf_size) - if (!(buf = av_realloc(buf, alloc_size))) + if (!(buf = av_realloc_f(buf, 1, alloc_size))) return AVERROR(ENOMEM); if (new_size > buf_size) { @@ -1049,7 +1066,7 @@ int url_open_buf(AVIOContext **s, uint8_t *buf, int buf_size, int flags) if(!*s) return AVERROR(ENOMEM); ret = ffio_init_context(*s, buf, buf_size, - flags & AVIO_FLAG_WRITE, + (flags & AVIO_WRONLY || flags & AVIO_RDWR), NULL, NULL, NULL, NULL); if(ret != 0) av_freep(s); @@ -1090,7 +1107,7 @@ static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) } if (new_allocated_size > d->allocated_size) { - d->buffer = av_realloc(d->buffer, new_allocated_size); + d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size); if(d->buffer == NULL) return AVERROR(ENOMEM); d->allocated_size = new_allocated_size; diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index 768459a38d..643f25b661 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -122,6 +122,14 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale; st->codec->codec_tag = imgfmt.bmiHeader.biCompression; st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression); + if (st->codec->codec_id == CODEC_ID_RAWVIDEO && imgfmt.bmiHeader.biCompression== BI_RGB) { + st->codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE); + if (st->codec->extradata) { + st->codec->extradata_size = 9; + memcpy(st->codec->extradata, "BottomUp", 9); + } + } + st->duration = stream->info.dwLength; } @@ -165,7 +173,6 @@ static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt) res = AVIStreamRead(stream->handle, stream->read, stream->chunck_samples, pkt->data, stream->chunck_size, &read_size, NULL); - pkt->pts = stream->read; pkt->size = read_size; stream->read += stream->chunck_samples; diff --git a/libavformat/avlanguage.c b/libavformat/avlanguage.c index 525bf07d27..39f2560d94 100644 --- a/libavformat/avlanguage.c +++ b/libavformat/avlanguage.c @@ -20,6 +20,7 @@ #include "avlanguage.h" #include "libavutil/avstring.h" +#include "libavutil/common.h" #include #include #include @@ -736,7 +737,7 @@ const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_cod { int i; const LangEntry *entry = NULL; - const int NB_CODESPACES = sizeof(lang_table_counts)/sizeof(*lang_table_counts); + const int NB_CODESPACES = FF_ARRAY_ELEMS(lang_table_counts); if (target_codespace >= NB_CODESPACES) return NULL; diff --git a/libavformat/avs.c b/libavformat/avs.c index 355ae31f35..127639e7ee 100644 --- a/libavformat/avs.c +++ b/libavformat/avs.c @@ -163,10 +163,14 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt) sub_type = avio_r8(s->pb); type = avio_r8(s->pb); size = avio_rl16(s->pb); + if (size < 4) + return AVERROR_INVALIDDATA; avs->remaining_frame_size -= size; switch (type) { case AVS_PALETTE: + if (size - 4 > sizeof(palette)) + return AVERROR_INVALIDDATA; ret = avio_read(s->pb, palette, size - 4); if (ret < size - 4) return AVERROR(EIO); diff --git a/libavformat/crypto.c b/libavformat/crypto.c index 5e7ee1eba3..d52a503e38 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -76,12 +76,12 @@ static int crypto_open(URLContext *h, const char *uri, int flags) ret = AVERROR(EINVAL); goto err; } - if (flags & AVIO_FLAG_WRITE) { + if (flags == AVIO_WRONLY) { av_log(h, AV_LOG_ERROR, "Only decryption is supported currently\n"); ret = AVERROR(ENOSYS); goto err; } - if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ)) < 0) { + if ((ret = ffurl_open(&c->hd, nested_url, AVIO_RDONLY)) < 0) { av_log(h, AV_LOG_ERROR, "Unable to open input\n"); goto err; } diff --git a/libavformat/dv.c b/libavformat/dv.c index 750c950df8..b02009c8e4 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -119,16 +119,23 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], if (quant > 1) return -1; /* unsupported quantization */ + if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) + return AVERROR_INVALIDDATA; + size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ half_ch = sys->difseg_size / 2; /* We work with 720p frames split in half, thus even frames have * channels 0,1 and odd 2,3. */ ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0; - pcm = ppcm[ipcm++]; /* for each DIF channel */ for (chan = 0; chan < sys->n_difchan; chan++) { + /* next stereo channel (50Mbps and 100Mbps only) */ + pcm = ppcm[ipcm++]; + if (!pcm) + break; + /* for each DIF segment */ for (i = 0; i < sys->difseg_size; i++) { frame += 6 * 80; /* skip DIF segment header */ @@ -176,11 +183,6 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ } } - - /* next stereo channel (50Mbps and 100Mbps only) */ - pcm = ppcm[ipcm++]; - if (!pcm) - break; } return size; @@ -202,6 +204,18 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ + if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) { + av_log(c->fctx, AV_LOG_ERROR, + "Unrecognized audio sample rate index (%d)\n", freq); + return 0; + } + + if (stype > 3) { + av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype); + c->ach = 0; + return 0; + } + /* note: ach counts PAIRS of channels (i.e. stereo channels) */ ach = ((int[4]){ 1, 0, 2, 4})[stype]; if (ach == 1 && quant && freq == 2) @@ -336,7 +350,8 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate; ppcm[i] = c->audio_buf[i]; } - dv_extract_audio(buf, ppcm, c->sys); + if (c->ach) + dv_extract_audio(buf, ppcm, c->sys); /* We work with 720p frames split in half, thus even frames have * channels 0,1 and odd 2,3. */ diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 0b882aac87..8e44fadb55 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -470,12 +470,17 @@ static int ea_read_packet(AVFormatContext *s, while (!packet_read) { chunk_type = avio_rl32(pb); - chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; + chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); + if (chunk_size <= 8) + return AVERROR_INVALIDDATA; + chunk_size -= 8; switch (chunk_type) { /* audio data */ case ISNh_TAG: /* header chunk also contains data; skip over the header portion*/ + if (chunk_size < 32) + return AVERROR_INVALIDDATA; avio_skip(pb, 32); chunk_size -= 32; case ISNd_TAG: diff --git a/libavformat/file.c b/libavformat/file.c index a9c5281102..88b5527521 100644 --- a/libavformat/file.c +++ b/libavformat/file.c @@ -58,8 +58,9 @@ static int file_check(URLContext *h, int mask) if (ret < 0) return AVERROR(errno); - ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0; - ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0; + ret |= st.st_mode&S_IRUSR ? mask&AVIO_RDONLY : 0; + ret |= st.st_mode&S_IWUSR ? mask&AVIO_WRONLY : 0; + ret |= st.st_mode&S_IWUSR && st.st_mode&S_IRUSR ? mask&AVIO_RDWR : 0; return ret; } @@ -73,9 +74,9 @@ static int file_open(URLContext *h, const char *filename, int flags) av_strstart(filename, "file:", &filename); - if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) { + if (flags & AVIO_RDWR) { access = O_CREAT | O_TRUNC | O_RDWR; - } else if (flags & AVIO_FLAG_WRITE) { + } else if (flags & AVIO_WRONLY) { access = O_CREAT | O_TRUNC | O_WRONLY; } else { access = O_RDONLY; @@ -131,7 +132,7 @@ static int pipe_open(URLContext *h, const char *filename, int flags) fd = strtol(filename, &final, 10); if((filename == final) || *final ) {/* No digits found, or something like 10ab */ - if (flags & AVIO_FLAG_WRITE) { + if (flags & AVIO_WRONLY) { fd = 1; } else { fd = 0; diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 3dd3e1f70f..3d2550f54d 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -116,11 +116,9 @@ static int flac_read_header(AVFormatContext *s, static int flac_probe(AVProbeData *p) { - uint8_t *bufptr = p->buf; - uint8_t *end = p->buf + p->buf_size; - - if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0; - else return AVPROBE_SCORE_MAX/2; + if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) + return 0; + return AVPROBE_SCORE_MAX/2; } AVInputFormat ff_flac_demuxer = { diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 4fb562f4e2..c9c6d7e898 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -173,8 +173,8 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream } } - if (timeslen == fileposlen) { - for(i = 0; i < timeslen; i++) + if (!ret && timeslen == fileposlen) { + for (i = 0; i < fileposlen; i++) av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME); } else av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); @@ -210,7 +210,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst case AMF_DATA_TYPE_OBJECT: { unsigned int keylen; - if (ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1) + if (vstream && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1) if (parse_keyframes_index(s, ioc, vstream, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); @@ -269,6 +269,10 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst vcodec->bit_rate = num_val * 1024.0; else if(!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0)) acodec->bit_rate = num_val * 1024.0; + } else if(amf_type == AMF_DATA_TYPE_OBJECT){ + if(s->nb_streams==1 && ((!acodec && !strcmp(key, "audiocodecid")) || (!vcodec && !strcmp(key, "videocodecid")))){ + s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object + } } else if (amf_type == AMF_DATA_TYPE_STRING) av_dict_set(&s->metadata, key, str_val, 0); } diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index cea0d02e3c..d56b4284cb 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -179,7 +179,7 @@ static int flv_write_header(AVFormatContext *s) AVCodecContext *audio_enc = NULL, *video_enc = NULL; int i; double framerate = 0.0; - int metadata_size_pos, data_size; + int64_t metadata_size_pos, data_size; AVDictionaryEntry *tag = NULL; for(i=0; inb_streams; i++){ diff --git a/libavformat/gopher.c b/libavformat/gopher.c index 9eeffaca28..3ab7357e56 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -50,7 +50,7 @@ static int gopher_connect(URLContext *h, const char *path) if (!path) return AVERROR(EINVAL); break; default: - av_log(h, AV_LOG_WARNING, + av_log(NULL, AV_LOG_WARNING, "Gopher protocol type '%c' not supported yet!\n", *path); return AVERROR(EINVAL); @@ -100,7 +100,7 @@ static int gopher_open(URLContext *h, const char *uri, int flags) ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); s->hd = NULL; - err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE); + err = ffurl_open(&s->hd, buf, AVIO_RDWR); if (err < 0) goto fail; diff --git a/libavformat/gxf.c b/libavformat/gxf.c index e278b9b846..50dc2f04ae 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -264,7 +264,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { int map_len; int len; AVRational main_timebase = {0, 0}; - struct gxf_stream_info si; + struct gxf_stream_info *si = s->priv_data; int i; if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) { av_log(s, AV_LOG_ERROR, "map packet not found\n"); @@ -282,7 +282,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { return 0; } map_len -= len; - gxf_material_tags(pb, &len, &si); + gxf_material_tags(pb, &len, si); avio_skip(pb, len); map_len -= 2; len = avio_rb16(pb); // length of track description @@ -300,7 +300,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { track_id = avio_r8(pb); track_len = avio_rb16(pb); len -= track_len; - gxf_track_tags(pb, &track_len, &si); + gxf_track_tags(pb, &track_len, si); avio_skip(pb, track_len); if (!(track_type & 0x80)) { av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type); @@ -316,12 +316,12 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { if (idx < 0) continue; st = s->streams[idx]; if (!main_timebase.num || !main_timebase.den) { - main_timebase.num = si.frames_per_second.den; - main_timebase.den = si.frames_per_second.num * 2; + main_timebase.num = si->frames_per_second.den; + main_timebase.den = si->frames_per_second.num * 2; } - st->start_time = si.first_field; - if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE) - st->duration = si.last_field - si.first_field; + st->start_time = si->first_field; + if (si->first_field != AV_NOPTS_VALUE && si->last_field != AV_NOPTS_VALUE) + st->duration = si->last_field - si->first_field; } if (len < 0) av_log(s, AV_LOG_ERROR, "invalid track description length specified\n"); @@ -422,6 +422,8 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; GXFPktType pkt_type; int pkt_len; + struct gxf_stream_info *si = s->priv_data; + while (!url_feof(pb)) { AVStream *st; int track_type, track_id, ret; @@ -473,13 +475,18 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { avio_skip(pb, skip); pkt->stream_index = stream_index; pkt->dts = field_nr; + + //set duration manually for DV or else lavf misdetects the frame rate + if (st->codec->codec_id == CODEC_ID_DVVIDEO) + pkt->duration = si->fields_per_frame; + return ret; } return AVERROR(EIO); } 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]; @@ -518,7 +525,7 @@ static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index, AVInputFormat ff_gxf_demuxer = { "gxf", NULL_IF_CONFIG_SMALL("GXF format"), - 0, + sizeof(struct gxf_stream_info), gxf_probe, gxf_header, gxf_packet, diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c index 3f7d7851f7..36e2c91ef6 100644 --- a/libavformat/gxfenc.c +++ b/libavformat/gxfenc.c @@ -340,8 +340,9 @@ static int gxf_write_map_packet(AVFormatContext *s, int rewrite) if (!rewrite) { if (!(gxf->map_offsets_nb % 30)) { - gxf->map_offsets = av_realloc(gxf->map_offsets, - (gxf->map_offsets_nb+30)*sizeof(*gxf->map_offsets)); + gxf->map_offsets = av_realloc_f(gxf->map_offsets, + sizeof(*gxf->map_offsets), + gxf->map_offsets_nb+30); if (!gxf->map_offsets) { av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n"); return -1; @@ -876,8 +877,9 @@ static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if (!(gxf->flt_entries_nb % 500)) { - gxf->flt_entries = av_realloc(gxf->flt_entries, - (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries)); + gxf->flt_entries = av_realloc_f(gxf->flt_entries, + sizeof(*gxf->flt_entries), + gxf->flt_entries_nb+500); if (!gxf->flt_entries) { av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n"); return -1; diff --git a/libavformat/http.c b/libavformat/http.c index 95ba456cea..d66f730037 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -73,7 +73,7 @@ void ff_http_set_headers(URLContext *h, const char *headers) int len = strlen(headers); if (len && strcmp("\r\n", headers + len - 2)) - av_log(h, AV_LOG_ERROR, "No trailing CRLF found in HTTP header.\n"); + av_log(NULL, AV_LOG_ERROR, "No trailing CRLF found in HTTP header.\n"); av_strlcpy(s->headers, headers, sizeof(s->headers)); } @@ -127,7 +127,7 @@ static int http_open_cnx(URLContext *h) port = 80; ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE); + err = ffurl_open(&hd, buf, AVIO_RDWR); if (err < 0) goto fail; @@ -235,7 +235,7 @@ static int process_line(URLContext *h, char *line, int line_count, * don't abort until all headers have been parsed. */ if (s->http_code >= 400 && s->http_code < 600 && s->http_code != 401) { end += strspn(end, SPACE_CHARS); - av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", + av_log(NULL, AV_LOG_WARNING, "HTTP error %d %s\n", s->http_code, end); return -1; } @@ -265,6 +265,8 @@ static int process_line(URLContext *h, char *line, int line_count, s->filesize = atoll(slash+1); } h->is_streamed = 0; /* we _can_ in fact seek */ + } else if (!strcasecmp (tag, "Accept-Ranges") && !strncmp (p, "bytes", 5)) { + h->is_streamed = 0; } else if (!strcasecmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) { s->filesize = -1; s->chunksize = 0; @@ -299,7 +301,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr, /* send http header */ - post = h->flags & AVIO_FLAG_WRITE; + post = h->flags & AVIO_WRONLY; authstr = ff_http_auth_create_response(&s->auth_state, auth, path, post ? "POST" : "GET"); @@ -454,7 +456,7 @@ static int http_close(URLContext *h) HTTPContext *s = h->priv_data; /* signal end of chunked encoding if used */ - if ((h->flags & AVIO_FLAG_WRITE) && s->chunksize != -1) { + if ((h->flags & AVIO_WRONLY) && s->chunksize != -1) { ret = ffurl_write(s->hd, footer, sizeof(footer) - 1); ret = ret > 0 ? 0 : ret; } diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 930ab5c870..b20501701e 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -224,8 +224,17 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t unsync = flags & 0x80; - if (isv34 && flags & 0x40) /* Extended header present, just skip over it */ - avio_skip(s->pb, get_size(s->pb, 4)); + if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */ + int extlen = get_size(s->pb, 4); + if (version == 4) + extlen -= 4; // in v2.4 the length includes the length field we just read + + if (extlen < 0) { + reason = "invalid extended header length"; + goto error; + } + avio_skip(s->pb, extlen); + } while (len >= taghdrlen) { unsigned int tflags = 0; diff --git a/libavformat/idcin.c b/libavformat/idcin.c index baff2d446d..8fd84f0728 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -86,11 +86,13 @@ typedef struct IdcinDemuxContext { int audio_present; int64_t pts; + + AVPaletteControl palctrl; } 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 @@ -119,18 +121,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 */ @@ -170,6 +172,8 @@ static int idcin_read_header(AVFormatContext *s, if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != HUFFMAN_TABLE_SIZE) return AVERROR(EIO); + /* save a reference in order to transport the palette */ + st->codec->palctrl = &idcin->palctrl; /* if sample rate is 0, assume no audio */ if (sample_rate) { @@ -222,7 +226,6 @@ static int idcin_read_packet(AVFormatContext *s, int palette_scale; unsigned char r, g, b; unsigned char palette_buffer[768]; - uint32_t palette[256]; if (url_feof(s->pb)) return AVERROR(EIO); @@ -233,6 +236,7 @@ static int idcin_read_packet(AVFormatContext *s, return AVERROR(EIO); } else if (command == 1) { /* trigger a palette change */ + idcin->palctrl.palette_changed = 1; if (avio_read(pb, palette_buffer, 768) != 768) return AVERROR(EIO); /* scale the palette as necessary */ @@ -247,7 +251,7 @@ static int idcin_read_packet(AVFormatContext *s, r = palette_buffer[i * 3 ] << palette_scale; g = palette_buffer[i * 3 + 1] << palette_scale; b = palette_buffer[i * 3 + 2] << palette_scale; - palette[i] = (r << 16) | (g << 8) | (b); + idcin->palctrl.palette[i] = (r << 16) | (g << 8) | (b); } } @@ -258,15 +262,6 @@ static int idcin_read_packet(AVFormatContext *s, ret= av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; - if (command == 1) { - uint8_t *pal; - - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, - AVPALETTE_SIZE); - if (ret < 0) - return ret; - memcpy(pal, palette, AVPALETTE_SIZE); - } pkt->stream_index = idcin->video_stream_index; pkt->pts = idcin->pts; } else { diff --git a/libavformat/iff.c b/libavformat/iff.c index db988a6ecd..cd5695e9b7 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -185,6 +185,11 @@ static int iff_read_header(AVFormatContext *s, break; case ID_CMAP: + if (data_size < 3 || data_size > 768 || data_size % 3) { + av_log(s, AV_LOG_ERROR, "Invalid CMAP chunk size %d\n", + data_size); + return AVERROR_INVALIDDATA; + } st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) diff --git a/libavformat/img2.c b/libavformat/img2.c index b6082c68f8..11ebf12d43 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -143,11 +143,11 @@ static int find_image_range(int *pfirst_index, int *plast_index, if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){ *pfirst_index = *plast_index = 1; - if (avio_check(buf, AVIO_FLAG_READ) > 0) + if(url_exist(buf)) return 0; return -1; } - if (avio_check(buf, AVIO_FLAG_READ) > 0) + if (url_exist(buf)) break; } if (first_index == 5) @@ -165,7 +165,7 @@ static int find_image_range(int *pfirst_index, int *plast_index, if (av_get_frame_filename(buf, sizeof(buf), path, last_index + range1) < 0) goto fail; - if (avio_check(buf, AVIO_FLAG_READ) <= 0) + if (!url_exist(buf)) break; range = range1; /* just in case... */ @@ -314,7 +314,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) s->path, s->img_number)<0 && s->img_number > 1) return AVERROR(EIO); for(i=0; i<3; i++){ - if (avio_open(&f[i], filename, AVIO_FLAG_READ) < 0) { + if (avio_open(&f[i], filename, AVIO_RDONLY) < 0) { if(i==1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename); @@ -401,7 +401,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); } for(i=0; i<3; i++){ - if (avio_open(&pb[i], filename, AVIO_FLAG_WRITE) < 0) { + if (avio_open(&pb[i], filename, AVIO_WRONLY) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } diff --git a/libavformat/internal.h b/libavformat/internal.h index e0d04db43f..1972993970 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -83,6 +83,18 @@ void ff_read_frame_flush(AVFormatContext *s); /** Get the current time since NTP epoch in microseconds. */ uint64_t ff_ntp_time(void); +#if FF_API_URL_SPLIT +/** + * @deprecated use av_url_split() instead + */ +void ff_url_split(char *proto, int proto_size, + char *authorization, int authorization_size, + char *hostname, int hostname_size, + int *port_ptr, + char *path, int path_size, + const char *url); +#endif + /** * Assemble a URL string from components. This is the reverse operation * of av_url_split. @@ -155,14 +167,14 @@ void ff_put_v(AVIOContext *bc, uint64_t val); /** * Read a whole line of text from AVIOContext. Stop reading after reaching - * either a \n, a \0 or EOF. The returned string is always \0 terminated, + * either a \\n, a \\0 or EOF. The returned string is always \\0-terminated, * and may be truncated if the buffer is too small. * * @param s the read-only AVIOContext * @param buf buffer to store the read line * @param maxlen size of the buffer * @return the length of the string written in the buffer, not including the - * final \0 + * final \\0 */ int ff_get_line(AVIOContext *s, char *buf, int maxlen); diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index b6da2911e9..471d6a4bc0 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -86,8 +86,6 @@ typedef struct IPMVEContext { unsigned int video_width; unsigned int video_height; int64_t video_pts; - uint32_t palette[256]; - int has_palette; unsigned int audio_bits; unsigned int audio_channels; @@ -107,6 +105,8 @@ typedef struct IPMVEContext { int64_t next_chunk_offset; + AVPaletteControl palette_control; + } IPMVEContext; static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, @@ -151,17 +151,6 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; - if (s->has_palette) { - uint8_t *pal; - - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, - AVPALETTE_SIZE); - if (pal) { - memcpy(pal, s->palette, AVPALETTE_SIZE); - s->has_palette = 0; - } - } - pkt->pos= s->decode_map_chunk_offset; avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); s->decode_map_chunk_offset = 0; @@ -455,9 +444,10 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, r = scratch[j++] * 4; g = scratch[j++] * 4; b = scratch[j++] * 4; - s->palette[i] = (r << 16) | (g << 8) | (b); + s->palette_control.palette[i] = (r << 16) | (g << 8) | (b); } - s->has_palette = 1; + /* indicate a palette change */ + s->palette_control.palette_changed = 1; break; case OPCODE_SET_PALETTE_COMPRESSED: @@ -571,6 +561,9 @@ static int ipmovie_read_header(AVFormatContext *s, st->codec->height = ipmovie->video_height; st->codec->bits_per_coded_sample = ipmovie->video_bpp; + /* palette considerations */ + st->codec->palctrl = &ipmovie->palette_control; + if (ipmovie->audio_type) { st = av_new_stream(s, 0); if (!st) diff --git a/libavformat/isom.c b/libavformat/isom.c index 33a448da34..162ef5369d 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -149,10 +149,13 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG2 HDV 1080i50 */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG2 HDV 720p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG2 HDV 720p25 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG2 HDV 1080p30 */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG2 HDV 720p60 JVC */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG2 HDV 720p50 */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG2 IMX NTSC 525/60 40mb/s produced by FCP */ @@ -183,6 +186,8 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ + { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */ + { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */ { CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ { CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ @@ -208,6 +213,8 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'o') }, /* Apple ProRes 422 Proxy */ { CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */ + { CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */ + { CODEC_ID_NONE, 0 }, }; @@ -246,7 +253,7 @@ const AVCodecTag codec_movaudio_tags[] = { { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */ { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */ { CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* mp4ra.org */ - { CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non standard */ + { CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */ { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */ { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ @@ -395,7 +402,7 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext len = ff_mp4_read_descr(fc, pb, &tag); if (tag == MP4DecSpecificDescrTag) { av_dlog(fc, "Specific MPEG4 header len=%d\n", len); - if((uint64_t)len > (1<<30)) + if (!len || (uint64_t)len > (1<<30)) return -1; av_free(st->codec->extradata); st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); diff --git a/libavformat/isom.h b/libavformat/isom.h index 2b64486129..43fa477a7d 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -123,8 +123,6 @@ typedef struct MOVStreamContext { int width; ///< tkhd width int height; ///< tkhd height int dts_shift; ///< dts shift when ctts is negative - uint32_t palette[256]; - int has_palette; } MOVStreamContext; typedef struct MOVContext { diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c index acc4503d89..4ada91887f 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -94,7 +94,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) goto fail; } - if (flags & AVIO_FLAG_WRITE) + if (flags & AVIO_WRONLY) RTMP_EnableWrite(r); if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) { diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 6e951bac18..ac91f67ad5 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -664,16 +664,19 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num) */ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) { - av_free(*str); + char *res; + /* EBML strings are usually not 0-terminated, so we allocate one * byte more, read the string and NULL-terminate it ourselves. */ - if (!(*str = av_malloc(size + 1))) + if (!(res = av_malloc(size + 1))) return AVERROR(ENOMEM); - if (avio_read(pb, (uint8_t *) *str, size) != size) { - av_freep(str); + if (avio_read(pb, (uint8_t *) res, size) != size) { + av_free(res); return AVERROR(EIO); } - (*str)[size] = '\0'; + (res)[size] = '\0'; + av_free(*str); + *str = res; return 0; } @@ -826,11 +829,15 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska, uint32_t id = syntax->id; uint64_t length; int res; + void *newelem; data = (char *)data + syntax->data_offset; if (syntax->list_elem_size) { EbmlList *list = data; - list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size); + newelem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size); + if (!newelem) + return AVERROR(ENOMEM); + list->elem = newelem; data = (char*)list->elem + list->nb_elem*syntax->list_elem_size; memset(data, 0, syntax->list_elem_size); list->nb_elem++; @@ -928,6 +935,8 @@ static int matroska_probe(AVProbeData *p) * Not fully fool-proof, but good enough. */ for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) { int probelen = strlen(matroska_doctypes[i]); + if (total < probelen) + continue; for (n = 4+size; n <= 4+size+total-probelen; n++) if (!memcmp(p->buf+n, matroska_doctypes[i], probelen)) return AVPROBE_SCORE_MAX; @@ -958,6 +967,7 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size, uint8_t* data = *buf; int isize = *buf_size; uint8_t* pkt_data = NULL; + uint8_t* newpktdata; int pkt_size = isize; int result = 0; int olen; @@ -987,10 +997,18 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size, zstream.avail_in = isize; do { pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size); + newpktdata = av_realloc(pkt_data, pkt_size); + if (!newpktdata) { + inflateEnd(&zstream); + goto failed; + } + pkt_data = newpktdata; zstream.avail_out = pkt_size - zstream.total_out; zstream.next_out = pkt_data + zstream.total_out; - result = inflate(&zstream, Z_NO_FLUSH); + if (pkt_data) { + result = inflate(&zstream, Z_NO_FLUSH); + } else + result = Z_MEM_ERROR; } while (result==Z_OK && pkt_size<10000000); pkt_size = zstream.total_out; inflateEnd(&zstream); @@ -1008,10 +1026,18 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size, bzstream.avail_in = isize; do { pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size); + newpktdata = av_realloc(pkt_data, pkt_size); + if (!newpktdata) { + BZ2_bzDecompressEnd(&bzstream); + goto failed; + } + pkt_data = newpktdata; bzstream.avail_out = pkt_size - bzstream.total_out_lo32; bzstream.next_out = pkt_data + bzstream.total_out_lo32; - result = BZ2_bzDecompress(&bzstream); + if (pkt_data) { + result = BZ2_bzDecompress(&bzstream); + } else + result = BZ_MEM_ERROR; } while (result==BZ_OK && pkt_size<10000000); pkt_size = bzstream.total_out_lo32; BZ2_bzDecompressEnd(&bzstream); @@ -1064,13 +1090,17 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska, } } -static void matroska_merge_packets(AVPacket *out, AVPacket *in) +static int matroska_merge_packets(AVPacket *out, AVPacket *in) { - out->data = av_realloc(out->data, out->size+in->size); + void *newdata = av_realloc(out->data, out->size+in->size); + if (!newdata) + return AVERROR(ENOMEM); + out->data = newdata; memcpy(out->data+out->size, in->data, in->size); out->size += in->size; av_destruct_packet(in); av_free(in); + return 0; } static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, @@ -1142,7 +1172,6 @@ static void matroska_convert_tags(AVFormatContext *s) static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) { EbmlList *seekhead_list = &matroska->seekhead; - MatroskaSeekhead *seekhead = seekhead_list->elem; uint32_t level_up = matroska->level_up; int64_t before_pos = avio_tell(matroska->ctx->pb); uint32_t saved_id = matroska->current_id; @@ -1155,6 +1184,7 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) return; for (i=0; inb_elem; i++) { + MatroskaSeekhead *seekhead = seekhead_list->elem; int64_t offset = seekhead[i].pos + matroska->segment_start; if (seekhead[i].pos <= before_pos @@ -1372,7 +1402,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) && track->codec_priv.data != NULL) { int ret; ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size, - AVIO_FLAG_READ, NULL, NULL, NULL, NULL); + AVIO_RDONLY, NULL, NULL, NULL, NULL); ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size); if (ret < 0) return ret; @@ -1400,7 +1430,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) } else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) { int profile = matroska_aac_profile(track->codec_id); int sri = matroska_aac_sri(track->audio.samplerate); - extradata = av_malloc(5); + extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE); if (extradata == NULL) return AVERROR(ENOMEM); extradata[0] = (profile << 3) | ((sri&0x0E) >> 1); @@ -1624,11 +1654,13 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); av_free(matroska->packets[0]); if (matroska->num_packets > 1) { + void *newpackets; memmove(&matroska->packets[0], &matroska->packets[1], (matroska->num_packets - 1) * sizeof(AVPacket *)); - matroska->packets = - av_realloc(matroska->packets, (matroska->num_packets - 1) * - sizeof(AVPacket *)); + newpackets = av_realloc(matroska->packets, + (matroska->num_packets - 1) * sizeof(AVPacket *)); + if (newpackets) + matroska->packets = newpackets; } else { av_freep(&matroska->packets); } @@ -1644,6 +1676,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++) { @@ -1782,7 +1815,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, lace_size[n] = lace_size[n - 1] + snum; total += lace_size[n]; } - lace_size[n] = size - total; + lace_size[laces - 1] = size - total; break; } } @@ -1807,15 +1840,31 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, if (!track->audio.pkt_cnt) { if (track->audio.sub_packet_cnt == 0) track->audio.buf_timecode = timecode; - if (st->codec->codec_id == CODEC_ID_RA_288) + if (st->codec->codec_id == CODEC_ID_RA_288) { + if (size < cfs * h / 2) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt int4 RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } for (x=0; xaudio.buf+x*2*w+y*cfs, data+x*cfs, cfs); - else if (st->codec->codec_id == CODEC_ID_SIPR) + } else if (st->codec->codec_id == CODEC_ID_SIPR) { + if (size < w) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt sipr RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } memcpy(track->audio.buf + y*w, data, w); - else + } else { + if (size < sps * w / sps) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt generic RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } for (x=0; xaudio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); + } if (++track->audio.sub_packet_cnt >= h) { if (st->codec->codec_id == CODEC_ID_SIPR) @@ -1959,6 +2008,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { 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_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0) @@ -1979,14 +2029,16 @@ 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--; } } avio_seek(s->pb, st->index_entries[index_min].pos, SEEK_SET); + matroska->current_id = 0; matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY); matroska->skip_to_timecode = st->index_entries[index].timestamp; matroska->done = 0; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index e9c977a59f..986373c4cd 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1209,7 +1209,6 @@ AVOutputFormat ff_matroska_muxer = { mkv_write_packet, mkv_write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .subtitle_codec = CODEC_ID_TEXT, }; #endif @@ -1243,6 +1242,5 @@ AVOutputFormat ff_matroska_audio_muxer = { mkv_write_packet, mkv_write_trailer, .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, }; #endif diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index 3f099da440..35a0d31305 100644 --- a/libavformat/md5proto.c +++ b/libavformat/md5proto.c @@ -36,7 +36,7 @@ static int md5_open(URLContext *h, const char *filename, int flags) return -1; } - if (!flags & AVIO_FLAG_WRITE) + if (flags != AVIO_WRONLY) return AVERROR(EINVAL); av_md5_init(h->priv_data); @@ -65,7 +65,7 @@ static int md5_close(URLContext *h) av_strstart(filename, "md5:", &filename); if (*filename) { - err = ffurl_open(&out, filename, AVIO_FLAG_WRITE); + err = ffurl_open(&out, filename, AVIO_WRONLY); if (err) return err; err = ffurl_write(out, buf, i*2+1); diff --git a/libavformat/metadata-example.c b/libavformat/metadata-example.c new file mode 100644 index 0000000000..7bf77e7378 --- /dev/null +++ b/libavformat/metadata-example.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Reinhard Tartler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @file + * @example libavformat/metadata-example.c + * Shows how the metadata API can be used in application programs. + */ + +#include + +#include +#include + +int main (int argc, char **argv) +{ + AVFormatContext *fmt_ctx = NULL; + AVDictionaryEntry *tag = NULL; + int ret; + + if (argc != 2) { + printf("usage: %s \n" + "example program to demonstrate the use of the libavformat metadata API.\n" + "\n", argv[0]); + return 1; + } + + av_register_all(); + if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL))) + return ret; + + while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + printf("%s=%s\n", tag->key, tag->value); + + avformat_free_context(fmt_ctx); + return 0; +} diff --git a/libavformat/metadata.c b/libavformat/metadata.c index e6fbe30da9..8caeffa316 100644 --- a/libavformat/metadata.c +++ b/libavformat/metadata.c @@ -34,6 +34,15 @@ int av_metadata_set2(AVDictionary **pm, const char *key, const char *value, int { return av_dict_set(pm, key, value, flags); } +#endif +#if FF_API_OLD_METADATA +int av_metadata_set(AVMetadata **pm, const char *key, const char *value) +{ + return av_metadata_set2(pm, key, value, 0); +} +#endif + +#if FF_API_OLD_METADATA2 void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv) diff --git a/libavformat/metadata.h b/libavformat/metadata.h index d826c6f144..aa96118f80 100644 --- a/libavformat/metadata.h +++ b/libavformat/metadata.h @@ -39,6 +39,11 @@ struct AVMetadataConv{ typedef struct AVMetadataConv AVMetadataConv; #endif +#if FF_API_OLD_METADATA +void ff_metadata_demux_compat(AVFormatContext *s); +void ff_metadata_mux_compat(AVFormatContext *s); +#endif + void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv); void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, diff --git a/libavformat/metadata_compat.c b/libavformat/metadata_compat.c new file mode 100644 index 0000000000..19b8f59df1 --- /dev/null +++ b/libavformat/metadata_compat.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2009 Aurelien Jacobs + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "avformat.h" +#include "metadata.h" +#include "libavutil/avstring.h" + +#if FF_API_OLD_METADATA + +#define SIZE_OFFSET(x) sizeof(((AVFormatContext*)0)->x),offsetof(AVFormatContext,x) + +static const struct { + const char name[16]; + int size; + int offset; +} compat_tab[] = { + { "title", SIZE_OFFSET(title) }, + { "author", SIZE_OFFSET(author) }, + { "copyright", SIZE_OFFSET(copyright) }, + { "comment", SIZE_OFFSET(comment) }, + { "album", SIZE_OFFSET(album) }, + { "year", SIZE_OFFSET(year) }, + { "track", SIZE_OFFSET(track) }, + { "genre", SIZE_OFFSET(genre) }, + + { "artist", SIZE_OFFSET(author) }, + { "creator", SIZE_OFFSET(author) }, + { "written_by", SIZE_OFFSET(author) }, + { "lead_performer", SIZE_OFFSET(author) }, + { "composer", SIZE_OFFSET(author) }, + { "performer", SIZE_OFFSET(author) }, + { "description", SIZE_OFFSET(comment) }, + { "albumtitle", SIZE_OFFSET(album) }, + { "date", SIZE_OFFSET(year) }, + { "date_written", SIZE_OFFSET(year) }, + { "date_released", SIZE_OFFSET(year) }, + { "tracknumber", SIZE_OFFSET(track) }, + { "part_number", SIZE_OFFSET(track) }, +}; + +void ff_metadata_demux_compat(AVFormatContext *ctx) +{ + AVMetadata *m; + int i, j; + + if ((m = ctx->metadata)) + for (j=0; jcount; j++) + for (i=0; ielems[j].key, compat_tab[i].name)) { + int *ptr = (int *)((char *)ctx+compat_tab[i].offset); + if (*ptr) continue; + if (compat_tab[i].size > sizeof(int)) + av_strlcpy((char *)ptr, m->elems[j].value, compat_tab[i].size); + else + *ptr = atoi(m->elems[j].value); + } + + for (i=0; inb_chapters; i++) + if ((m = ctx->chapters[i]->metadata)) + for (j=0; jcount; j++) + if (!strcasecmp(m->elems[j].key, "title")) { + av_free(ctx->chapters[i]->title); + ctx->chapters[i]->title = av_strdup(m->elems[j].value); + } + + for (i=0; inb_programs; i++) + if ((m = ctx->programs[i]->metadata)) + for (j=0; jcount; j++) { + if (!strcasecmp(m->elems[j].key, "name")) { + av_free(ctx->programs[i]->name); + ctx->programs[i]->name = av_strdup(m->elems[j].value); + } + if (!strcasecmp(m->elems[j].key, "provider_name")) { + av_free(ctx->programs[i]->provider_name); + ctx->programs[i]->provider_name = av_strdup(m->elems[j].value); + } + } + + for (i=0; inb_streams; i++) + if ((m = ctx->streams[i]->metadata)) + for (j=0; jcount; j++) { + if (!strcasecmp(m->elems[j].key, "language")) + av_strlcpy(ctx->streams[i]->language, m->elems[j].value, 4); + if (!strcasecmp(m->elems[j].key, "filename")) { + av_free(ctx->streams[i]->filename); + ctx->streams[i]->filename= av_strdup(m->elems[j].value); + } + } +} + + +#define FILL_METADATA(s, key, value) { \ + if (!av_metadata_get(s->metadata, #key, NULL, 0)) \ + av_metadata_set2(&s->metadata, #key, value, 0); \ + } +#define FILL_METADATA_STR(s, key) { \ + if (s->key && *s->key) FILL_METADATA(s, key, s->key); } +#define FILL_METADATA_INT(s, key) { \ + char number[10]; \ + snprintf(number, sizeof(number), "%d", s->key); \ + if(s->key) FILL_METADATA(s, key, number) } + +void ff_metadata_mux_compat(AVFormatContext *ctx) +{ + int i; + + if (ctx->metadata && ctx->metadata->count > 0) + return; + + FILL_METADATA_STR(ctx, title); + FILL_METADATA_STR(ctx, author); + FILL_METADATA_STR(ctx, copyright); + FILL_METADATA_STR(ctx, comment); + FILL_METADATA_STR(ctx, album); + FILL_METADATA_INT(ctx, year); + FILL_METADATA_INT(ctx, track); + FILL_METADATA_STR(ctx, genre); + for (i=0; inb_chapters; i++) + FILL_METADATA_STR(ctx->chapters[i], title); + for (i=0; inb_programs; i++) { + FILL_METADATA_STR(ctx->programs[i], name); + FILL_METADATA_STR(ctx->programs[i], provider_name); + } + for (i=0; inb_streams; i++) { + FILL_METADATA_STR(ctx->streams[i], language); + FILL_METADATA_STR(ctx->streams[i], filename); + } +} + +#endif /* FF_API_OLD_METADATA */ diff --git a/libavformat/mms.c b/libavformat/mms.c index 46fbede90c..b541208e31 100644 --- a/libavformat/mms.c +++ b/libavformat/mms.c @@ -24,7 +24,11 @@ #include "asf.h" #include "libavutil/intreadwrite.h" +#if FF_API_MAX_STREAMS +#define MMS_MAX_STREAMS MAX_STREAMS +#else #define MMS_MAX_STREAMS 256 /**< arbitrary sanity check value */ +#endif int ff_mms_read_header(MMSContext *mms, uint8_t *buf, const int size) { diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index a66e1d9ab2..4b296e30d9 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -233,7 +233,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) port = 80; // default mmsh protocol port ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path); - if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) { + if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_RDONLY) < 0) { return AVERROR(EIO); } @@ -261,7 +261,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) // close the socket and then reopen it for sending the second play request. ffurl_close(mms->mms_hd); memset(headers, 0, sizeof(headers)); - if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) { + if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_RDONLY) < 0) { return AVERROR(EIO); } stream_selection = av_mallocz(mms->stream_num * 19 + 1); diff --git a/libavformat/mmst.c b/libavformat/mmst.c index a3db288b35..7c1041ec85 100644 --- a/libavformat/mmst.c +++ b/libavformat/mmst.c @@ -523,7 +523,7 @@ static int mms_open(URLContext *h, const char *uri, int flags) // establish tcp connection. ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); - err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE); + err = ffurl_open(&mms->mms_hd, tcpname, AVIO_RDWR); if (err) goto fail; diff --git a/libavformat/mov.c b/libavformat/mov.c index 773760c98a..8fd9b320a3 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -755,7 +755,8 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom) } /* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */ -static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom) +static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, + enum CodecID codec_id) { AVStream *st; uint64_t size; @@ -764,6 +765,10 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (c->fc->nb_streams < 1) // will happen with jp2 files return 0; st= c->fc->streams[c->fc->nb_streams-1]; + + if (st->codec->codec_id != codec_id) + return 0; /* unexpected codec_id - don't mess with extradata */ + size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE; if(size > INT_MAX || (uint64_t)atom.size > INT_MAX) return -1; @@ -779,6 +784,27 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */ +static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + return mov_read_extradata(c, pb, atom, CODEC_ID_ALAC); +} + +static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + return mov_read_extradata(c, pb, atom, CODEC_ID_AVS); +} + +static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + return mov_read_extradata(c, pb, atom, CODEC_ID_MJPEG); +} + +static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + return mov_read_extradata(c, pb, atom, CODEC_ID_JPEG2000); +} + static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; @@ -1043,6 +1069,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) unsigned int color_start, color_count, color_end; unsigned char r, g, b; + st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl)); if (color_greyscale) { int color_index, color_dec; /* compute the greyscale palette */ @@ -1052,7 +1079,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) color_dec = 256 / (color_count - 1); for (j = 0; j < color_count; j++) { r = g = b = color_index; - sc->palette[j] = + st->codec->palctrl->palette[j] = (r << 16) | (g << 8) | (b); color_index -= color_dec; if (color_index < 0) @@ -1073,7 +1100,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) r = color_table[j * 3 + 0]; g = color_table[j * 3 + 1]; b = color_table[j * 3 + 2]; - sc->palette[j] = + st->codec->palctrl->palette[j] = (r << 16) | (g << 8) | (b); } } else { @@ -1095,12 +1122,12 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) avio_r8(pb); b = avio_r8(pb); avio_r8(pb); - sc->palette[j] = + st->codec->palctrl->palette[j] = (r << 16) | (g << 8) | (b); } } } - sc->has_palette = 1; + st->codec->palctrl->palette_changed = 1; } } else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) { int bits_per_sample, flags; @@ -1738,7 +1765,7 @@ static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref) av_strlcat(filename, ref->path + l + 1, 1024); - if (!avio_open(pb, filename, AVIO_FLAG_READ)) + if (!avio_open(pb, filename, AVIO_RDONLY)) return 0; } } @@ -2228,7 +2255,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) } static const MOVParseTableEntry mov_default_parse_table[] = { -{ MKTAG('a','v','s','s'), mov_read_extradata }, +{ MKTAG('a','v','s','s'), mov_read_avss }, { MKTAG('c','h','p','l'), mov_read_chpl }, { MKTAG('c','o','6','4'), mov_read_stco }, { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */ @@ -2237,12 +2264,12 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('e','d','t','s'), mov_read_default }, { MKTAG('e','l','s','t'), mov_read_elst }, { MKTAG('e','n','d','a'), mov_read_enda }, -{ MKTAG('f','i','e','l'), mov_read_extradata }, +{ MKTAG('f','i','e','l'), mov_read_fiel }, { MKTAG('f','t','y','p'), mov_read_ftyp }, { MKTAG('g','l','b','l'), mov_read_glbl }, { MKTAG('h','d','l','r'), mov_read_hdlr }, { MKTAG('i','l','s','t'), mov_read_ilst }, -{ MKTAG('j','p','2','h'), mov_read_extradata }, +{ MKTAG('j','p','2','h'), mov_read_jp2h }, { MKTAG('m','d','a','t'), mov_read_mdat }, { MKTAG('m','d','h','d'), mov_read_mdhd }, { MKTAG('m','d','i','a'), mov_read_default }, @@ -2253,7 +2280,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('m','v','e','x'), mov_read_default }, { MKTAG('m','v','h','d'), mov_read_mvhd }, { MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */ -{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */ +{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */ { MKTAG('a','v','c','C'), mov_read_glbl }, { MKTAG('p','a','s','p'), mov_read_pasp }, { MKTAG('s','t','b','l'), mov_read_default }, @@ -2376,14 +2403,21 @@ static void mov_read_chapters(AVFormatContext *s) // The samples could theoretically be in any encoding if there's an encd // atom following, but in practice are only utf-8 or utf-16, distinguished // instead by the presence of a BOM - ch = avio_rb16(sc->pb); - if (ch == 0xfeff) - avio_get_str16be(sc->pb, len, title, title_len); - else if (ch == 0xfffe) - avio_get_str16le(sc->pb, len, title, title_len); - else { - AV_WB16(title, ch); - get_strz(sc->pb, title + 2, len - 1); + if (!len) { + title[0] = 0; + } else { + ch = avio_rb16(sc->pb); + if (ch == 0xfeff) + avio_get_str16be(sc->pb, len, title, title_len); + else if (ch == 0xfffe) + avio_get_str16le(sc->pb, len, title, title_len); + else { + AV_WB16(title, ch); + if (len == 1 || len == 2) + title[len] = 0; + else + get_strz(sc->pb, title + 2, len - 1); + } } ff_new_chapter(s, i, st->time_base, sample->timestamp, end, title); @@ -2481,17 +2515,6 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) ret = av_get_packet(sc->pb, pkt, sample->size); if (ret < 0) return ret; - if (sc->has_palette) { - uint8_t *pal; - - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); - if (!pal) { - av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n"); - } else { - memcpy(pal, sc->palette, AVPALETTE_SIZE); - sc->has_palette = 0; - } - } #if CONFIG_DV_DEMUXER if (mov->dv_demux && sc->dv_audio_container) { dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); diff --git a/libavformat/movenc.c b/libavformat/movenc.c index ebfcacb107..4448628eb1 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -206,7 +206,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) avio_wb32(pb, 11); ffio_wfourcc(pb, "dac3"); - init_get_bits(&gbc, track->vosData+4, track->vosLen-4); + init_get_bits(&gbc, track->vosData+4, (track->vosLen-4) * 8); fscod = get_bits(&gbc, 2); frmsizecod = get_bits(&gbc, 6); bsid = get_bits(&gbc, 5); @@ -1223,7 +1223,8 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) avio_wb32(pb, 0); /* reserved */ avio_wb32(pb, 0); /* reserved */ - avio_wb32(pb, 0x0); /* reserved (Layer & Alternate group) */ + avio_wb16(pb, 0); /* layer */ + avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */ /* Volume, only for audio */ if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO) avio_wb16(pb, 0x0100); @@ -2058,7 +2059,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) { - trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster)); + trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE)); if (!trk->cluster) return -1; } diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 64f6ea8c0e..5e3e3513ad 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -109,8 +109,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) if(avio_rb16(s->pb) == 1) { /* skip delay and quality */ avio_skip(s->pb, 4); - frames = avio_rb32(s->pb); size = avio_rb32(s->pb); + frames = avio_rb32(s->pb); } } @@ -173,7 +173,9 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = 0; if (ret <= 0) { - return AVERROR(EIO); + if(ret<0) + return ret; + return AVERROR_EOF; } if (ret > ID3v1_TAG_SIZE && diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 50342bb950..76d1813172 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -51,11 +51,12 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) buf[0] = 'T'; buf[1] = 'A'; buf[2] = 'G'; - count += id3v1_set_string(s, "TIT2", buf + 3, 30); //title - count += id3v1_set_string(s, "TPE1", buf + 33, 30); //author|artist - count += id3v1_set_string(s, "TALB", buf + 63, 30); //album - count += id3v1_set_string(s, "TDRL", buf + 93, 4); //date - count += id3v1_set_string(s, "comment", buf + 97, 30); + /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */ + count += id3v1_set_string(s, "TIT2", buf + 3, 30 + 1); //title + count += id3v1_set_string(s, "TPE1", buf + 33, 30 + 1); //author|artist + count += id3v1_set_string(s, "TALB", buf + 63, 30 + 1); //album + count += id3v1_set_string(s, "TDRL", buf + 93, 4 + 1); //date + count += id3v1_set_string(s, "comment", buf + 97, 30 + 1); if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track buf[125] = 0; buf[126] = atoi(tag->value); diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index b18726c6db..3193f5d570 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -54,7 +54,7 @@ typedef struct { static inline int64_t bs_get_v(uint8_t **bs) { - int64_t v = 0; + uint64_t v = 0; int br = 0; int c; @@ -88,7 +88,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) @@ -105,7 +105,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; @@ -204,6 +204,10 @@ static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap) while(!url_feof(pb)){ pos = avio_tell(pb); mpc8_get_chunk_header(pb, &tag, &size); + if (size < 0) { + av_log(s, AV_LOG_ERROR, "Invalid chunk length\n"); + return AVERROR_INVALIDDATA; + } if(tag == TAG_STREAMHDR) break; mpc8_handle_chunk(s, tag, pos, size); @@ -264,7 +268,7 @@ static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EIO); mpc8_handle_chunk(s, tag, pos, size); } - return 0; + return AVERROR_EOF; } static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 1bc4480cd8..b4bd1e50c6 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -106,6 +106,7 @@ static int mpegps_read_header(AVFormatContext *s, MpegDemuxContext *m = s->priv_data; const char *sofdec = "Sofdec"; int v, i = 0; + int64_t last_pos = avio_tell(s->pb); m->header_state = 0xff; s->ctx_flags |= AVFMTCTX_NOHEADER; @@ -119,6 +120,9 @@ static int mpegps_read_header(AVFormatContext *s, m->sofdec = (m->sofdec == 6) ? 1 : 0; + if (!m->sofdec) + avio_seek(s->pb, last_pos, SEEK_SET); + /* no need to do more */ return 0; } @@ -419,7 +423,7 @@ static int mpegps_read_packet(AVFormatContext *s, { MpegDemuxContext *m = s->priv_data; AVStream *st; - int len, startcode, i, es_type; + int len, startcode, i, es_type, ret; int request_probe= 0; enum CodecID codec_id = CODEC_ID_NONE; enum AVMediaType type; @@ -564,8 +568,7 @@ static int mpegps_read_packet(AVFormatContext *s, else if (st->codec->bits_per_coded_sample == 28) return AVERROR(EINVAL); } - av_new_packet(pkt, len); - avio_read(s->pb, pkt->data, pkt->size); + ret = av_get_packet(s->pb, pkt, len); pkt->pts = pts; pkt->dts = dts; pkt->pos = dummy_pos; @@ -574,7 +577,7 @@ static int mpegps_read_packet(AVFormatContext *s, pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size); - return 0; + return (ret < 0) ? ret : 0; } static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 74c9ac931c..28ec4926f5 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -700,6 +700,11 @@ static int mpegts_push_data(MpegTSFilter *filter, code == 0x1be) /* padding_stream */ goto skip; +#if FF_API_MAX_STREAMS + if (!pes->st && pes->stream->nb_streams == MAX_STREAMS) + goto skip; +#endif + /* stream not present in PMT */ if (!pes->st) { pes->st = av_new_stream(ts->stream, pes->pid); @@ -1083,7 +1088,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len // stop parsing after pmt, we found header if (!ts->stream->nb_streams) - ts->stop_parse = 1; + ts->stop_parse = 2; for(;;) { st = 0; @@ -1174,12 +1179,18 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (sid == 0x0000) { /* NIT info */ } else { + MpegTSFilter *fil = ts->pids[pmt_pid]; program = av_new_program(ts->stream, sid); program->program_num = sid; program->pmt_pid = pmt_pid; - if (ts->pids[pmt_pid]) - mpegts_close_filter(ts, ts->pids[pmt_pid]); - mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); + if (fil) + if ( fil->type != MPEGTS_SECTION + || fil->pid != pmt_pid + || fil->u.section_filter.section_cb != pmt_cb) + mpegts_close_filter(ts, ts->pids[pmt_pid]); + + if (!ts->pids[pmt_pid]) + mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); add_pat_entry(ts, sid); add_pid_to_pmt(ts, sid, 0); //add pat pid to program add_pid_to_pmt(ts, sid, pmt_pid); @@ -1229,7 +1240,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", @@ -1268,7 +1279,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) { AVFormatContext *s = ts->stream; MpegTSFilter *tss; - int len, pid, cc, cc_ok, afc, is_start; + int len, pid, cc, expected_cc, cc_ok, afc, is_start; const uint8_t *p, *p_end; int64_t pos; @@ -1286,7 +1297,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) /* continuity check (currently not used) */ cc = (packet[3] & 0xf); - cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc)); + expected_cc = (packet[3] & 0x10) ? (tss->last_cc + 1) & 0x0f : tss->last_cc; + cc_ok = (tss->last_cc < 0) || (expected_cc == cc); tss->last_cc = cc; /* skip adaptation field */ @@ -1402,11 +1414,15 @@ static int handle_packets(MpegTSContext *ts, int nb_packets) ts->stop_parse = 0; packet_num = 0; for(;;) { - if (ts->stop_parse>0) - break; packet_num++; - if (nb_packets != 0 && packet_num >= nb_packets) + if (nb_packets != 0 && packet_num >= nb_packets || + ts->stop_parse > 1) { + ret = AVERROR(EAGAIN); break; + } + if (ts->stop_parse > 0) + break; + ret = read_packet(s, packet, ts->raw_packet_size); if (ret != 0) return ret; @@ -1857,10 +1873,8 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, len1 = len; ts->pkt = pkt; - ts->stop_parse = 0; for(;;) { - if (ts->stop_parse>0) - break; + ts->stop_parse = 0; if (len < TS_PACKET_SIZE) return -1; if (buf[0] != 0x47) { @@ -1870,6 +1884,8 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, handle_packet(ts, buf); buf += TS_PACKET_SIZE; len -= TS_PACKET_SIZE; + if (ts->stop_parse == 1) + break; } } return len1 - len; diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 7e9647257f..45a6f2213b 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -23,6 +23,7 @@ #include "libavutil/crc.h" #include "libavutil/dict.h" #include "libavutil/opt.h" +#include "libavutil/avassert.h" #include "libavcodec/mpegvideo.h" #include "avformat.h" #include "internal.h" @@ -84,7 +85,7 @@ static const AVOption options[] = { { "mpegts_service_id", "Set service_id field.", offsetof(MpegTSWrite, service_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", - offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM}, + offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM}, { "mpegts_start_pid", "Set the first pid.", offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM}, { NULL }, @@ -947,19 +948,20 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) } } - if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) { + if (ts_st->payload_index && ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) { + mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, + ts_st->payload_pts, ts_st->payload_dts); + ts_st->payload_index = 0; + } + + if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO || size > DEFAULT_PES_PAYLOAD_SIZE) { + av_assert0(!ts_st->payload_index); // for video and subtitle, write a single pes packet mpegts_write_pes(s, st, buf, size, pts, dts); av_free(data); return 0; } - if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) { - mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, - ts_st->payload_pts, ts_st->payload_dts); - ts_st->payload_index = 0; - } - if (!ts_st->payload_index) { ts_st->payload_pts = pts; ts_st->payload_dts = dts; diff --git a/libavformat/mxf.c b/libavformat/mxf.c index 643a95243a..50ea3b5648 100644 --- a/libavformat/mxf.c +++ b/libavformat/mxf.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/common.h" #include "mxf.h" /** @@ -80,7 +81,7 @@ static const struct { {PIX_FMT_PAL8, {'P', 8 }}, }; -static const int num_pixel_layouts = sizeof(ff_mxf_pixel_layouts) / sizeof(*ff_mxf_pixel_layouts); +static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts); int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum PixelFormat *pix_fmt) { diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 8548c792f6..953d3b0002 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -223,12 +223,13 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, if (length > 61444) /* worst case PAL 1920 samples 8 channels */ return -1; - av_new_packet(pkt, length); - avio_read(pb, pkt->data, length); + length = av_get_packet(pb, pkt, length); + if (length < 0) + return length; data_ptr = pkt->data; end_ptr = pkt->data + length; buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */ - for (; buf_ptr < end_ptr; ) { + for (; buf_ptr + st->codec->channels*4 < end_ptr; ) { for (i = 0; i < st->codec->channels; i++) { uint32_t sample = bytestream_get_le32(&buf_ptr); if (st->codec->bits_per_coded_sample == 24) @@ -238,7 +239,7 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, } buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M } - pkt->size = data_ptr - pkt->data; + av_shrink_packet(pkt, data_ptr - pkt->data); return 0; } @@ -290,12 +291,16 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv if (memcmp(tmpbuf, checkv, 16)) av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n"); size -= 32; - av_get_packet(pb, pkt, size); + size = av_get_packet(pb, pkt, size); + if (size < 0) + return size; + else if (size < plaintext_size) + return AVERROR_INVALIDDATA; size -= plaintext_size; if (mxf->aesc) av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size], &pkt->data[plaintext_size], size >> 4, ivec, 1); - pkt->size = orig_size; + av_shrink_packet(pkt, orig_size); pkt->stream_index = index; avio_skip(pb, end - avio_tell(pb)); return 0; @@ -332,8 +337,11 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); return -1; } - } else - av_get_packet(s->pb, pkt, klv.length); + } else { + int ret = av_get_packet(s->pb, pkt, klv.length); + if (ret < 0) + return ret; + } pkt->stream_index = index; pkt->pos = klv.offset; return 0; @@ -599,7 +607,7 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int default: /* Private uid used by SONY C0023S01.mxf */ if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) { - descriptor->extradata = av_malloc(size); + descriptor->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!descriptor->extradata) return -1; descriptor->extradata_size = size; diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index c6532a3427..0f230cb224 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -1539,7 +1539,7 @@ static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0 static uint32_t ff_framenum_to_12m_time_code(unsigned frame, int drop, int fps) { return (0 << 31) | // color frame flag - (0 << 30) | // drop frame flag + (drop << 30) | // drop frame flag ( ((frame % fps) / 10) << 28) | // tens of frames ( ((frame % fps) % 10) << 24) | // units of frames (0 << 23) | // field phase (NTSC), b0 (PAL) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 4898187f3a..7791d3aa6e 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -308,7 +308,9 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) char *token, *value; char quote; - p = strings = av_mallocz(strings_size + 1); + p = strings = av_mallocz((size_t)strings_size + 1); + if (!p) + return AVERROR(ENOMEM); endp = strings + strings_size; avio_read(pb, strings, strings_size); while (p < endp) { @@ -343,6 +345,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t)) return -1; nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t)); + if (!nsv->nsvs_file_offset) + return AVERROR(ENOMEM); for(i=0;insvs_file_offset[i] = avio_rl32(pb) + size; @@ -350,6 +354,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) if(table_entries > table_entries_used && avio_rl32(pb) == MKTAG('T','O','C','2')) { nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t)); + if (!nsv->nsvs_timestamps) + return AVERROR(ENOMEM); for(i=0;insvs_timestamps[i] = avio_rl32(pb); } @@ -518,11 +524,16 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap) for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) { if (nsv_resync(s) < 0) return -1; - if (nsv->state == NSV_FOUND_NSVF) + if (nsv->state == NSV_FOUND_NSVF) { err = nsv_parse_NSVf_header(s, ap); + if (err < 0) + return err; + } /* we need the first NSVs also... */ if (nsv->state == NSV_FOUND_NSVS) { err = nsv_parse_NSVs_header(s, ap); + if (err < 0) + return err; break; /* we just want the first one */ } } @@ -597,12 +608,12 @@ null_chunk_retry: } /* map back streams to v,a */ - if (s->streams[0]) + if (s->nb_streams > 0) st[s->streams[0]->id] = s->streams[0]; - if (s->streams[1]) + if (s->nb_streams > 1) st[s->streams[1]->id] = s->streams[1]; - if (vsize/* && st[NSV_ST_VIDEO]*/) { + if (vsize && st[NSV_ST_VIDEO]) { nst = st[NSV_ST_VIDEO]->priv_data; pkt = &nsv->ahead[NSV_ST_VIDEO]; av_get_packet(pb, pkt, vsize); @@ -615,7 +626,7 @@ null_chunk_retry: if(st[NSV_ST_VIDEO]) ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++; - if (asize/*st[NSV_ST_AUDIO]*/) { + if (asize && st[NSV_ST_AUDIO]) { nst = st[NSV_ST_AUDIO]->priv_data; pkt = &nsv->ahead[NSV_ST_AUDIO]; /* read raw audio specific header on the first audio chunk... */ diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 7aecf73b73..8af0c48bfc 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -31,7 +31,11 @@ #undef NDEBUG #include +#if FF_API_MAX_STREAMS +#define NUT_MAX_STREAMS MAX_STREAMS +#else #define NUT_MAX_STREAMS 256 /* arbitrary sanity check value */ +#endif static int get_str(AVIOContext *bc, char *string, unsigned int maxlen){ unsigned int len= ffio_read_varlen(bc); diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 655da35dd4..e103290056 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -29,7 +29,6 @@ DEALINGS IN THE SOFTWARE. **/ - #include #include "oggdec.h" #include "avformat.h" @@ -70,8 +69,7 @@ static int ogg_save(AVFormatContext *s) for (i = 0; i < ogg->nstreams; i++){ struct ogg_stream *os = ogg->streams + i; - os->buf = av_malloc (os->bufsize); - memset (os->buf, 0, os->bufsize); + os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); memcpy (os->buf, ost->streams[i].buf, os->bufpos); } @@ -93,14 +91,24 @@ static int ogg_restore(AVFormatContext *s, int discard) ogg->state = ost->next; if (!discard){ + struct ogg_stream *old_streams = ogg->streams; + for (i = 0; i < ogg->nstreams; i++) av_free (ogg->streams[i].buf); avio_seek (bc, ost->pos, SEEK_SET); ogg->curidx = ost->curidx; ogg->nstreams = ost->nstreams; - memcpy(ogg->streams, ost->streams, - ost->nstreams * sizeof(*ogg->streams)); + ogg->streams = av_realloc (ogg->streams, + ogg->nstreams * sizeof (*ogg->streams)); + + if (ogg->streams) { + memcpy(ogg->streams, ost->streams, + ost->nstreams * sizeof(*ogg->streams)); + } else { + av_free(old_streams); + ogg->nstreams = 0; + } } av_free (ost); @@ -152,13 +160,18 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream) AVStream *st; struct ogg_stream *os; - ogg->streams = av_realloc (ogg->streams, - ogg->nstreams * sizeof (*ogg->streams)); + os = av_realloc (ogg->streams, ogg->nstreams * sizeof (*ogg->streams)); + + if (!os) + return AVERROR(ENOMEM); + + ogg->streams = os; + memset (ogg->streams + idx, 0, sizeof (*ogg->streams)); os = ogg->streams + idx; os->serial = serial; os->bufsize = DECODER_BUFFER_SIZE; - os->buf = av_malloc(os->bufsize); + os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); os->header = -1; if (new_avstream) { @@ -175,7 +188,7 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream) static int ogg_new_buf(struct ogg *ogg, int idx) { struct ogg_stream *os = ogg->streams + idx; - uint8_t *nb = av_malloc(os->bufsize); + uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); int size = os->bufpos - os->pstart; if(os->buf){ memcpy(nb, os->buf + os->pstart, size); @@ -240,7 +253,8 @@ static int ogg_read_page(AVFormatContext *s, int *str) for (n = 0; n < ogg->nstreams; n++) { av_freep(&ogg->streams[n].buf); - av_freep(&ogg->streams[n].private); + if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private) + av_freep(&ogg->streams[n].private); } ogg->curidx = -1; ogg->nstreams = 0; @@ -285,7 +299,9 @@ static int ogg_read_page(AVFormatContext *s, int *str) } if (os->bufsize - os->bufpos < size){ - uint8_t *nb = av_malloc (os->bufsize *= 2); + uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE); + if (!nb) + return AVERROR(ENOMEM); memcpy (nb, os->buf, os->bufpos); av_free (os->buf); os->buf = nb; @@ -299,6 +315,7 @@ static int ogg_read_page(AVFormatContext *s, int *str) os->granule = gp; os->flags = flags; + memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE); if (str) *str = idx; @@ -494,14 +511,32 @@ static int ogg_get_length(AVFormatContext *s) return 0; } -static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap) +static int ogg_read_close(AVFormatContext *s) { struct ogg *ogg = s->priv_data; - int ret, i; + int i; + + for (i = 0; i < ogg->nstreams; i++) { + av_free(ogg->streams[i].buf); + if (ogg->streams[i].codec && + ogg->streams[i].codec->cleanup) { + ogg->streams[i].codec->cleanup(s, i); + } + av_free(ogg->streams[i].private); + } + av_free(ogg->streams); + return 0; +} + +static int ogg_read_header(AVFormatContext *s) +{ + struct ogg *ogg = s->priv_data; + int i, ret; ogg->curidx = -1; //linear headers seek from start - ret = ogg_get_headers (s); - if (ret < 0){ + ret = ogg_get_headers(s); + if (ret < 0) { + ogg_read_close(s); return ret; } @@ -586,32 +621,19 @@ 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) { struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + stream_index; AVIOContext *bc = s->pb; int64_t pts = AV_NOPTS_VALUE; - int i; + int i = -1; avio_seek(bc, *pos_arg, SEEK_SET); ogg_reset(ogg); while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) { if (i == stream_index) { + struct ogg_stream *os = ogg->streams + stream_index; pts = ogg_calc_pts(s, i, NULL); if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY)) pts = AV_NOPTS_VALUE; @@ -637,6 +659,7 @@ static int ogg_read_seek(AVFormatContext *s, int stream_index, os->keyframe_seek = 1; ret = av_seek_frame_binary(s, stream_index, timestamp, flags); + os = ogg->streams + stream_index; if (ret < 0) os->keyframe_seek = 0; return ret; diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h index 184a628622..1a702c32d2 100644 --- a/libavformat/oggdec.h +++ b/libavformat/oggdec.h @@ -51,6 +51,11 @@ struct ogg_codec { * 0 if granule is the end time of the associated packet. */ int granule_is_start; + /** + * Number of expected headers + */ + int nb_header; + void (*cleanup)(AVFormatContext *s, int idx); }; struct ogg_stream { diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index 5d1f320351..04f536f157 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -71,7 +71,7 @@ typedef struct { static const AVOption options[] = { { "oggpagesize", "Set preferred Ogg page size.", - offsetof(OGGContext, pref_size), FF_OPT_TYPE_INT, 0, 0, MAX_PAGE_SIZE, AV_OPT_FLAG_ENCODING_PARAM}, + offsetof(OGGContext, pref_size), FF_OPT_TYPE_INT, {.dbl=0}, 0, MAX_PAGE_SIZE, AV_OPT_FLAG_ENCODING_PARAM}, { NULL }, }; diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index 86951f3e2f..514ed9ff28 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -188,6 +188,16 @@ fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv, return offset; } +static void vorbis_cleanup(AVFormatContext *s, int idx) +{ + struct ogg *ogg = s->priv_data; + struct ogg_stream *os = ogg->streams + idx; + struct oggvorbis_private *priv = os->private; + int i; + if (os->private) + for (i = 0; i < 3; i++) + av_freep(&priv->packet[i]); +} static int vorbis_header (AVFormatContext * s, int idx) @@ -278,5 +288,7 @@ vorbis_header (AVFormatContext * s, int idx) const struct ogg_codec ff_vorbis_codec = { .magic = "\001vorbis", .magicsize = 7, - .header = vorbis_header + .header = vorbis_header, + .cleanup= vorbis_cleanup, + .nb_header = 3, }; diff --git a/libavformat/options.c b/libavformat/options.c index e09fc97a25..ef3261b8b6 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -122,3 +122,10 @@ AVFormatContext *avformat_alloc_context(void) avformat_get_context_defaults(ic); return ic; } + +#if FF_API_ALLOC_FORMAT_CONTEXT +AVFormatContext *av_alloc_format_context(void) +{ + return avformat_alloc_context(); +} +#endif diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c index 744ae94459..b65bddd5c1 100644 --- a/libavformat/psxstr.c +++ b/libavformat/psxstr.c @@ -68,6 +68,8 @@ static const char sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf static int str_probe(AVProbeData *p) { uint8_t *sector= p->buf; + uint8_t *end= sector + p->buf_size; + int aud=0, vid=0; if (p->buf_size < RAW_CD_SECTOR_SIZE) return 0; @@ -79,20 +81,52 @@ static int str_probe(AVProbeData *p) sector += RIFF_HEADER_SIZE; } - /* look for CD sync header (00, 0xFF x 10, 00) */ - if (memcmp(sector,sync_header,sizeof(sync_header))) - return 0; + while (end - sector >= RAW_CD_SECTOR_SIZE) { + /* look for CD sync header (00, 0xFF x 10, 00) */ + if (memcmp(sector,sync_header,sizeof(sync_header))) + return 0; - if(sector[0x11] >= 32) - return 0; - if( (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_VIDEO - && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_AUDIO - && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_DATA) - return 0; + if (sector[0x11] >= 32) + return 0; + switch (sector[0x12] & CDXA_TYPE_MASK) { + case CDXA_TYPE_DATA: + case CDXA_TYPE_VIDEO: { + int current_sector = AV_RL16(§or[0x1C]); + int sector_count = AV_RL16(§or[0x1E]); + int frame_size = AV_RL32(§or[0x24]); + + if(!( frame_size>=0 + && current_sector < sector_count + && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){ + return 0; + } + + /*st->codec->width = AV_RL16(§or[0x28]); + st->codec->height = AV_RL16(§or[0x2A]);*/ + +// if (current_sector == sector_count-1) { + vid++; +// } + + } + break; + case CDXA_TYPE_AUDIO: + if(sector[0x13]&0x2A) + return 0; + aud++; + break; + default: + if(sector[0x12] & CDXA_TYPE_MASK) + return 0; + } + sector += RAW_CD_SECTOR_SIZE; + } /* MPEG files (like those ripped from VCDs) can also look like this; * only return half certainty */ - return 50; + if(vid+aud > 3) return 50; + else if(vid+aud) return 1; + else return 0; } static int str_read_header(AVFormatContext *s, diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index a4e009b7e0..76e05237ca 100644 --- a/libavformat/rawdec.c +++ b/libavformat/rawdec.c @@ -59,6 +59,12 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap) if (s1->sample_rate) st->codec->sample_rate = s1->sample_rate; + if (st->codec->sample_rate <= 0) { + av_log(s, AV_LOG_WARNING, "Invalid sample rate %d specified using default of 44100\n", + st->codec->sample_rate); + st->codec->sample_rate= 44100; + } + if (s1->channels) st->codec->channels = s1->channels; @@ -246,7 +252,7 @@ AVInputFormat ff_gsm_demuxer = { #endif #if CONFIG_MJPEG_DEMUXER -FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg", CODEC_ID_MJPEG) +FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg,mpo", CODEC_ID_MJPEG) #endif #if CONFIG_MLP_DEMUXER diff --git a/libavformat/riff.c b/libavformat/riff.c index 544c29f116..a834084b71 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -130,6 +130,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('s', 'l', 'i', 'f') }, { CODEC_ID_MPEG2VIDEO, MKTAG('E', 'M', '2', 'V') }, { CODEC_ID_MPEG2VIDEO, MKTAG('M', '7', '0', '1') }, /* Matrox MPEG2 intra-only */ + { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', 'v') }, { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') }, { CODEC_ID_MJPEG, MKTAG('L', 'J', 'P', 'G') }, { CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, @@ -286,6 +287,7 @@ const AVCodecTag ff_codec_wav_tags[] = { { CODEC_ID_ADPCM_YAMAHA, 0x0020 }, { CODEC_ID_TRUESPEECH, 0x0022 }, { CODEC_ID_GSM_MS, 0x0031 }, + { CODEC_ID_AMR_NB, 0x0038 }, /* rogue format number */ { CODEC_ID_ADPCM_G726, 0x0045 }, { CODEC_ID_MP2, 0x0050 }, { CODEC_ID_MP3, 0x0055 }, diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index c2eee815c2..fec95a5714 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -26,6 +26,13 @@ #include "riff.h" #include "rm.h" +#define DEINT_ID_GENR MKTAG('g', 'e', 'n', 'r') ///< interleaving for Cooker/Atrac +#define DEINT_ID_INT0 MKTAG('I', 'n', 't', '0') ///< no interleaving needed +#define DEINT_ID_INT4 MKTAG('I', 'n', 't', '4') ///< interleaving for 28.8 +#define DEINT_ID_SIPR MKTAG('s', 'i', 'p', 'r') ///< interleaving for Sipro +#define DEINT_ID_VBRF MKTAG('v', 'b', 'r', 'f') ///< VBR case for AAC +#define DEINT_ID_VBRS MKTAG('v', 'b', 'r', 's') ///< VBR case for AAC + struct RMStream { AVPacket pkt; ///< place to store merged video frame / reordered audio data int videobufsize; ///< current assembled frame size @@ -39,6 +46,7 @@ struct RMStream { int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container int audio_framesize; /// Audio frame size from container int sub_packet_lengths[16]; /// Length of each subpacket + int32_t deint_id; ///< deinterleaver used in audio stream }; typedef struct { @@ -147,6 +155,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, st->codec->channels = 1; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_RA_144; + ast->deint_id = DEINT_ID_INT0; } else { int flavor, sub_packet_h, coded_framesize, sub_packet_size; int codecdata_length; @@ -172,17 +181,19 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, avio_rb32(pb); st->codec->channels = avio_rb16(pb); if (version == 5) { - avio_rb32(pb); + ast->deint_id = avio_rl32(pb); avio_read(pb, buf, 4); buf[4] = 0; } else { get_str8(pb, buf, sizeof(buf)); /* desc */ + ast->deint_id = AV_RL32(buf); get_str8(pb, buf, sizeof(buf)); /* desc */ } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = AV_RL32(buf); st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codec->codec_tag); + switch (st->codec->codec_id) { case CODEC_ID_AC3: st->need_parsing = AVSTREAM_PARSE_FULL; @@ -191,13 +202,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, st->codec->extradata_size= 0; ast->audio_framesize = st->codec->block_align; st->codec->block_align = coded_framesize; - - if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ - av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); - return -1; - } - - av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); break; case CODEC_ID_COOK: case CODEC_ID_ATRAC3: @@ -228,13 +232,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, } if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) return ret; - - if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ - av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); - return -1; - } - - av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); break; case CODEC_ID_AAC: avio_rb16(pb); avio_r8(pb); @@ -254,6 +251,37 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, default: av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name)); } + if (ast->deint_id == DEINT_ID_INT4 || + ast->deint_id == DEINT_ID_GENR || + ast->deint_id == DEINT_ID_SIPR) { + if (st->codec->block_align <= 0 || + ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || + ast->audio_framesize * sub_packet_h < st->codec->block_align) + return AVERROR_INVALIDDATA; + if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) + return AVERROR(ENOMEM); + } + switch (ast->deint_id) { + case DEINT_ID_INT4: + if (ast->coded_framesize > ast->audio_framesize || + ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize) + return AVERROR_INVALIDDATA; + break; + case DEINT_ID_GENR: + if (ast->sub_packet_size <= 0 || + ast->sub_packet_size > ast->audio_framesize) + return AVERROR_INVALIDDATA; + break; + case DEINT_ID_SIPR: + case DEINT_ID_INT0: + case DEINT_ID_VBRS: + case DEINT_ID_VBRF: + break; + default: + av_log(NULL,0,"Unknown interleaver %X\n", ast->deint_id); + return AVERROR_INVALIDDATA; + } + if (read_all) { avio_r8(pb); avio_r8(pb); @@ -350,8 +378,19 @@ static int rm_read_index(AVFormatContext *s) st = s->streams[n]; break; } - if (n == s->nb_streams) + if (n == s->nb_streams) { + av_log(s, AV_LOG_ERROR, + "Invalid stream index %d for index at pos %"PRId64"\n", + str_id, avio_tell(pb)); goto skip; + } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) { + av_log(s, AV_LOG_ERROR, + "Nr. of packets in packet index for stream index %d " + "exceeds filesize (%"PRId64" at %"PRId64" = %d)\n", + str_id, avio_size(pb), avio_tell(pb), + (avio_size(pb) - avio_tell(pb)) / 14); + goto skip; + } for (n = 0; n < n_pkts; n++) { avio_skip(pb, 2); @@ -363,9 +402,12 @@ static int rm_read_index(AVFormatContext *s) } skip: - if (next_off && avio_tell(pb) != next_off && - avio_seek(pb, next_off, SEEK_SET) < 0) + if (next_off && avio_tell(pb) < next_off && + avio_seek(pb, next_off, SEEK_SET) < 0) { + av_log(s, AV_LOG_ERROR, + "Non-linear index detected, not supported\n"); return -1; + } } while (next_off); return 0; @@ -712,10 +754,9 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq)) return -1; //got partial frame } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if ((st->codec->codec_id == CODEC_ID_RA_288) || - (st->codec->codec_id == CODEC_ID_COOK) || - (st->codec->codec_id == CODEC_ID_ATRAC3) || - (st->codec->codec_id == CODEC_ID_SIPR)) { + if ((ast->deint_id == DEINT_ID_GENR) || + (ast->deint_id == DEINT_ID_INT4) || + (ast->deint_id == DEINT_ID_SIPR)) { int x; int sps = ast->sub_packet_size; int cfs = ast->coded_framesize; @@ -728,30 +769,30 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, if (!y) ast->audiotimestamp = timestamp; - switch(st->codec->codec_id) { - case CODEC_ID_RA_288: + switch (ast->deint_id) { + case DEINT_ID_INT4: for (x = 0; x < h/2; x++) avio_read(pb, ast->pkt.data+x*2*w+y*cfs, cfs); break; - case CODEC_ID_ATRAC3: - case CODEC_ID_COOK: + case DEINT_ID_GENR: for (x = 0; x < w/sps; x++) avio_read(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); break; - case CODEC_ID_SIPR: + case DEINT_ID_SIPR: avio_read(pb, ast->pkt.data + y * w, w); break; } if (++(ast->sub_packet_cnt) < h) return -1; - if (st->codec->codec_id == CODEC_ID_SIPR) + if (ast->deint_id == DEINT_ID_SIPR) ff_rm_reorder_sipr_data(ast->pkt.data, h, w); ast->sub_packet_cnt = 0; rm->audio_stream_num = st->index; rm->audio_pkt_cnt = h * w / st->codec->block_align; - } else if (st->codec->codec_id == CODEC_ID_AAC) { + } else if ((ast->deint_id == DEINT_ID_VBRF) || + (ast->deint_id == DEINT_ID_VBRS)) { int x; rm->audio_stream_num = st->index; ast->sub_packet_cnt = (avio_rb16(pb) & 0xf0) >> 4; @@ -799,7 +840,8 @@ ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb, assert (rm->audio_pkt_cnt > 0); - if (st->codec->codec_id == CODEC_ID_AAC) + if (ast->deint_id == DEINT_ID_VBRF || + ast->deint_id == DEINT_ID_VBRS) av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); else { av_new_packet(pkt, st->codec->block_align); @@ -905,7 +947,9 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index, if(rm->old_format) return AV_NOPTS_VALUE; - avio_seek(s->pb, pos, SEEK_SET); + if (avio_seek(s->pb, pos, SEEK_SET) < 0) + return AV_NOPTS_VALUE; + rm->remaining_len=0; for(;;){ int seq=1; diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 4b6d549f74..c65cfc1439 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -278,11 +278,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; } @@ -311,7 +311,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)) { @@ -332,7 +332,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; } @@ -362,7 +362,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) @@ -381,7 +381,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); @@ -394,22 +394,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; } diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h index 4c28cd351e..8acbfc116b 100644 --- a/libavformat/rtmppkt.h +++ b/libavformat/rtmppkt.h @@ -138,7 +138,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p, void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p); /** - * @defgroup amffuncs functions used to work with AMF format (which is also used in .flv) + * @name Functions used to work with the AMF format (which is also used in .flv) * @see amf_* funcs in libavformat/flvdec.c * @{ */ diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index b8714c9ffa..3701a77176 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -38,6 +38,13 @@ #include "rtmppkt.h" #include "url.h" +/* we can't use av_log() with URLContext yet... */ +#if FF_API_URL_CLASS +#define LOG_CONTEXT s +#else +#define LOG_CONTEXT NULL +#endif + //#define DEBUG /** RTMP protocol handler state */ @@ -159,7 +166,7 @@ static void gen_release_stream(URLContext *s, RTMPContext *rt) ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 29 + strlen(rt->playpath)); - av_log(s, AV_LOG_DEBUG, "Releasing stream...\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Releasing stream...\n"); p = pkt.data; ff_amf_write_string(&p, "releaseStream"); ff_amf_write_number(&p, 2.0); @@ -182,7 +189,7 @@ static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt) ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 25 + strlen(rt->playpath)); - av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "FCPublish stream...\n"); p = pkt.data; ff_amf_write_string(&p, "FCPublish"); ff_amf_write_number(&p, 3.0); @@ -205,7 +212,7 @@ static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt) ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 27 + strlen(rt->playpath)); - av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "UnPublishing stream...\n"); p = pkt.data; ff_amf_write_string(&p, "FCUnpublish"); ff_amf_write_number(&p, 5.0); @@ -225,7 +232,7 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt) RTMPPacket pkt; uint8_t *p; - av_log(s, AV_LOG_DEBUG, "Creating stream...\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Creating stream...\n"); ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 25); p = pkt.data; @@ -247,7 +254,7 @@ static void gen_delete_stream(URLContext *s, RTMPContext *rt) RTMPPacket pkt; uint8_t *p; - av_log(s, AV_LOG_DEBUG, "Deleting stream...\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Deleting stream...\n"); ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 34); p = pkt.data; @@ -269,7 +276,7 @@ static void gen_play(URLContext *s, RTMPContext *rt) RTMPPacket pkt; uint8_t *p; - av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath); ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0, 20 + strlen(rt->playpath)); pkt.extra = rt->main_channel_id; @@ -303,7 +310,7 @@ static void gen_publish(URLContext *s, RTMPContext *rt) RTMPPacket pkt; uint8_t *p; - av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath); ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE, 0, 30 + strlen(rt->playpath)); pkt.extra = rt->main_channel_id; @@ -471,7 +478,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) int server_pos, client_pos; uint8_t digest[32]; - av_log(s, AV_LOG_DEBUG, "Handshaking...\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Handshaking...\n"); av_lfg_init(&rnd, 0xDEADC0DE); // generate handshake packet - 1536 bytes of pseudorandom data @@ -482,16 +489,16 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1); i = ffurl_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1); if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) { - av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); return -1; } i = ffurl_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE); if (i != RTMP_HANDSHAKE_PACKET_SIZE) { - av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); return -1; } - av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n", + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n", serverdata[5], serverdata[6], serverdata[7], serverdata[8]); if (rt->is_input && serverdata[5] >= 3) { @@ -499,7 +506,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) if (!server_pos) { server_pos = rtmp_validate_digest(serverdata + 1, 8); if (!server_pos) { - av_log(s, AV_LOG_ERROR, "Server response validating failed\n"); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server response validating failed\n"); return -1; } } @@ -511,7 +518,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) digest, 32, digest); if (memcmp(digest, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) { - av_log(s, AV_LOG_ERROR, "Signature mismatch\n"); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Signature mismatch\n"); return -1; } @@ -545,13 +552,13 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) const uint8_t *data_end = pkt->data + pkt->data_size; #ifdef DEBUG - ff_rtmp_packet_dump(s, pkt); + ff_rtmp_packet_dump(LOG_CONTEXT, pkt); #endif switch (pkt->type) { case RTMP_PT_CHUNK_SIZE: if (pkt->data_size != 4) { - av_log(s, AV_LOG_ERROR, + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Chunk size change packet is not 4 bytes long (%d)\n", pkt->data_size); return -1; } @@ -559,10 +566,10 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size, rt->prev_pkt[1]); rt->chunk_size = AV_RB32(pkt->data); if (rt->chunk_size <= 0) { - av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size); return -1; } - av_log(s, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size); break; case RTMP_PT_PING: t = AV_RB16(pkt->data); @@ -571,12 +578,12 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) break; case RTMP_PT_CLIENT_BW: if (pkt->data_size < 4) { - av_log(s, AV_LOG_ERROR, + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Client bandwidth report packet is less than 4 bytes long (%d)\n", pkt->data_size); return -1; } - av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data)); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data)); rt->client_report_size = AV_RB32(pkt->data) >> 1; break; case RTMP_PT_INVOKE: @@ -586,7 +593,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) if (!ff_amf_get_field_value(pkt->data + 9, data_end, "description", tmpstr, sizeof(tmpstr))) - av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr); return -1; } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { switch (rt->state) { @@ -617,7 +624,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) case STATE_CONNECTING: //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"); + av_log(LOG_CONTEXT, AV_LOG_WARNING, "Unexpected reply on connect()\n"); } else { rt->main_channel_id = (int) av_int2dbl(AV_RB64(pkt->data + 21)); } @@ -644,7 +651,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) if (!t && !strcmp(tmpstr, "error")) { if (!ff_amf_get_field_value(ptr, data_end, "description", tmpstr, sizeof(tmpstr))) - av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr); + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr); return -1; } t = ff_amf_get_field_value(ptr, data_end, @@ -694,7 +701,7 @@ static int get_packet(URLContext *s, int for_header) } rt->bytes_read += ret; if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) { - av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n"); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending bytes read report\n"); gen_bytes_read(s, rt, rpkt.timestamp + 1); rt->last_bytes_read = rt->bytes_read; } @@ -805,7 +812,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) if (!rt) return AVERROR(ENOMEM); s->priv_data = rt; - rt->is_input = !(flags & AVIO_FLAG_WRITE); + rt->is_input = !(flags & AVIO_WRONLY); av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), s->filename); @@ -814,8 +821,8 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) port = RTMP_DEFAULT_PORT; ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE) < 0) { - av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); + if (ffurl_open(&rt->stream, buf, AVIO_RDWR) < 0) { + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; } @@ -859,7 +866,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) rt->bytes_read = 0; rt->last_bytes_read = 0; - av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", proto, path, rt->app, rt->playpath); gen_connect(s, rt, proto, hostname, port); @@ -926,7 +933,7 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) const uint8_t *buf_temp = buf; if (size < 11) { - av_log(s, AV_LOG_DEBUG, "FLV packet too small %d\n", size); + av_log(LOG_CONTEXT, AV_LOG_DEBUG, "FLV packet too small %d\n", size); return 0; } diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 9fc30d7b66..db96a46849 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -82,6 +82,11 @@ void av_register_rtp_dynamic_payload_handlers(void) ff_register_dynamic_payload_handler(&ff_qt_rtp_vid_handler); ff_register_dynamic_payload_handler(&ff_quicktime_rtp_aud_handler); ff_register_dynamic_payload_handler(&ff_quicktime_rtp_vid_handler); + + ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler); + ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler); + ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler); + ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler); } RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name, @@ -111,14 +116,15 @@ RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id, static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len) { int payload_len; - while (len >= 2) { + while (len >= 4) { + payload_len = FFMIN(len, (AV_RB16(buf + 2) + 1) * 4); + switch (buf[1]) { case RTCP_SR: - if (len < 16) { + if (payload_len < 20) { av_log(NULL, AV_LOG_ERROR, "Invalid length for RTCP SR packet\n"); return AVERROR_INVALIDDATA; } - payload_len = (AV_RB16(buf + 2) + 1) * 4; s->last_rtcp_ntp_time = AV_RB64(buf + 8); s->last_rtcp_timestamp = AV_RB32(buf + 16); @@ -129,14 +135,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp; } - buf += payload_len; - len -= payload_len; break; case RTCP_BYE: return -RTCP_BYE; - default: - return -1; } + + buf += payload_len; + len -= payload_len; } return -1; } diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c index 4f776453d7..d97e8ee918 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -233,8 +233,16 @@ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf, int cur_len = start_off + len_off - off; int prev_len = out_len; + void *newmem; + out_len += cur_len; - asf->buf = av_realloc(asf->buf, out_len); + + if (FFMIN(cur_len, len - off) < 0) + return -1; + newmem = av_realloc(asf->buf, out_len); + if (!newmem) + return -1; + asf->buf = newmem; memcpy(asf->buf + prev_len, buf + off, FFMIN(cur_len, len - off)); avio_skip(pb, cur_len); diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h index 16f5a9d3e4..afd047be21 100644 --- a/libavformat/rtpdec_formats.h +++ b/libavformat/rtpdec_formats.h @@ -33,6 +33,10 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p); extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler; extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler; +extern RTPDynamicProtocolHandler ff_g726_16_dynamic_handler; +extern RTPDynamicProtocolHandler ff_g726_24_dynamic_handler; +extern RTPDynamicProtocolHandler ff_g726_32_dynamic_handler; +extern RTPDynamicProtocolHandler ff_g726_40_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler; extern RTPDynamicProtocolHandler ff_h264_dynamic_handler; diff --git a/libavformat/rtpdec_g726.c b/libavformat/rtpdec_g726.c new file mode 100644 index 0000000000..cde832b21a --- /dev/null +++ b/libavformat/rtpdec_g726.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011 Miroslav Slugeň + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "rtpdec_formats.h" + +static int g726_16_parse_sdp_line(AVFormatContext *s, int st_index, + PayloadContext *data, const char *line) +{ + AVStream *stream = s->streams[st_index]; + AVCodecContext *codec = stream->codec; + + codec->bit_rate = 16000; + + return 0; +} + +static int g726_24_parse_sdp_line(AVFormatContext *s, int st_index, + PayloadContext *data, const char *line) +{ + AVStream *stream = s->streams[st_index]; + AVCodecContext *codec = stream->codec; + + codec->bit_rate = 24000; + + return 0; +} + +static int g726_32_parse_sdp_line(AVFormatContext *s, int st_index, + PayloadContext *data, const char *line) +{ + AVStream *stream = s->streams[st_index]; + AVCodecContext *codec = stream->codec; + + codec->bit_rate = 32000; + + return 0; +} + +static int g726_40_parse_sdp_line(AVFormatContext *s, int st_index, + PayloadContext *data, const char *line) +{ + AVStream *stream = s->streams[st_index]; + AVCodecContext *codec = stream->codec; + + codec->bit_rate = 40000; + + return 0; +} + +RTPDynamicProtocolHandler ff_g726_16_dynamic_handler = { + .enc_name = "G726-16", + .codec_type = AVMEDIA_TYPE_AUDIO, + .codec_id = CODEC_ID_ADPCM_G726, + .parse_sdp_a_line = g726_16_parse_sdp_line, +}; + +RTPDynamicProtocolHandler ff_g726_24_dynamic_handler = { + .enc_name = "G726-24", + .codec_type = AVMEDIA_TYPE_AUDIO, + .codec_id = CODEC_ID_ADPCM_G726, + .parse_sdp_a_line = g726_24_parse_sdp_line, +}; + +RTPDynamicProtocolHandler ff_g726_32_dynamic_handler = { + .enc_name = "G726-32", + .codec_type = AVMEDIA_TYPE_AUDIO, + .codec_id = CODEC_ID_ADPCM_G726, + .parse_sdp_a_line = g726_32_parse_sdp_line, +}; + +RTPDynamicProtocolHandler ff_g726_40_dynamic_handler = { + .enc_name = "G726-40", + .codec_type = AVMEDIA_TYPE_AUDIO, + .codec_id = CODEC_ID_ADPCM_G726, + .parse_sdp_a_line = g726_40_parse_sdp_line, +}; diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 8b23f25c46..89c59cb877 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -115,6 +115,7 @@ static void build_udp_url(char *buf, int buf_size, url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size); if (connect) url_add_option(buf, buf_size, "connect=1"); + url_add_option(buf, buf_size, "fifo_size=0"); } /** diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index e8a0cd8198..f8525ea539 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -428,11 +428,6 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, } } -/** - * Parse the sdp description and allocate the rtp streams and the - * pollfd array used for udp ones. - */ - int ff_sdp_parse(AVFormatContext *s, const char *content) { RTSPState *rt = s->priv_data; @@ -1050,9 +1045,6 @@ retry: return 0; } -/** - * @return 0 on success, <0 on error, 1 if protocol is unavailable. - */ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, int lower_transport, const char *real_challenge) { @@ -1078,7 +1070,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) { char transport[2048]; - /** + /* * WMS serves all UDP data over a single connection, the RTX, which * isn't necessarily the first in the SDP but has to be the first * to be set up, else the second/third SETUP will fail with a 461. @@ -1118,14 +1110,14 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, "?localport=%d", j); /* we will use two ports per rtp stream (rtp and rtcp) */ j += 2; - if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE) == 0) + if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_RDWR) == 0) goto rtp_opened; } } #if 0 /* then try on any port */ - if (ffurl_open(&rtsp_st->rtp_handle, "rtp://", AVIO_FLAG_READ) < 0) { + if (ffurl_open(&rtsp_st->rtp_handle, "rtp://", AVIO_RDONLY) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1151,7 +1143,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, /* RTP/TCP */ else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) { - /** For WMS streams, the application streams are only used for + /* For WMS streams, the application streams are only used for * UDP. When trying to set it up for TCP streams, the server * will return an error. Therefore, we skip those streams. */ if (rt->server_type == RTSP_SERVER_WMS && @@ -1271,7 +1263,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); ff_url_join(url, sizeof(url), "rtp", NULL, namebuf, port, "?ttl=%d", ttl); - if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_RDWR) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1398,7 +1390,7 @@ redirect: av_get_random_seed(), av_get_random_seed()); /* GET requests */ - if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ) < 0) { + if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_RDONLY) < 0) { err = AVERROR(EIO); goto fail; } @@ -1419,7 +1411,7 @@ redirect: } /* POST requests */ - if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE) < 0 ) { + if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_WRONLY) < 0 ) { err = AVERROR(EIO); goto fail; } @@ -1462,7 +1454,7 @@ redirect: } else { /* open the tcp connection */ ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); - if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_RDWR) < 0) { err = AVERROR(EIO); goto fail; } @@ -1482,14 +1474,14 @@ redirect: cmd[0] = 0; if (rt->server_type == RTSP_SERVER_REAL) av_strlcat(cmd, - /** + /* * The following entries are required for proper * streaming from a Realmedia server. They are * interdependent in some way although we currently * don't quite understand how. Values were copied * from mplayer SVN r23589. - * @param CompanyID is a 16-byte ID in base64 - * @param ClientChallenge is a 16-byte ID in hex + * ClientChallenge is a 16-byte ID in hex + * CompanyID is a 16-byte ID in base64 */ "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n" "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n" @@ -1649,6 +1641,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) rt->cur_transport_priv = NULL; } +redo: if (rt->transport == RTSP_TRANSPORT_RTP) { int i; int64_t first_queue_time = 0; @@ -1664,12 +1657,15 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) first_queue_st = rt->rtsp_streams[i]; } } - if (first_queue_time) + if (first_queue_time) { wait_end = first_queue_time + s->max_delay; + } else { + wait_end = 0; + first_queue_st = NULL; + } } /* read next RTP packet */ - redo: if (!rt->recvbuf) { rt->recvbuf = av_malloc(RECVBUF_SIZE); if (!rt->recvbuf) @@ -1809,7 +1805,7 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) namebuf, rtsp_st->sdp_port, "?localport=%d&ttl=%d", rtsp_st->sdp_port, rtsp_st->sdp_ttl); - if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_RDWR) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1865,7 +1861,7 @@ static int rtp_read_header(AVFormatContext *s, if (!ff_network_init()) return AVERROR(EIO); - ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ); + ret = ffurl_open(&in, s->filename, AVIO_RDONLY); if (ret) goto fail; diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index 6b060923e4..f5cf823de3 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -505,8 +505,9 @@ int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply); int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr); /** - * Parse a SDP description of streams by populating an RTSPState struct - * within the AVFormatContext. + * Parse an SDP description of streams by populating an RTSPState struct + * within the AVFormatContext; also allocate the RTP streams and the + * pollfd array used for UDP streams. */ int ff_sdp_parse(AVFormatContext *s, const char *content); @@ -525,6 +526,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt); /** * Do the SETUP requests for each stream for the chosen * lower transport mode. + * @return 0 on success, <0 on error, 1 if protocol is unavailable */ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, int lower_transport, const char *real_challenge); diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index f6897fbb0b..e4d3deb60f 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -85,7 +85,7 @@ static int sap_read_header(AVFormatContext *s, ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d", port); - ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ); + ret = ffurl_open(&sap->ann_fd, url, AVIO_RDONLY); if (ret) goto fail; diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index 6cd3096d90..4ca14ad964 100644 --- a/libavformat/sapenc.c +++ b/libavformat/sapenc.c @@ -146,7 +146,7 @@ static int sap_write_header(AVFormatContext *s) "?ttl=%d", ttl); if (!same_port) base_port += 2; - ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE); + ret = ffurl_open(&fd, url, AVIO_WRONLY); if (ret) { ret = AVERROR(EIO); goto fail; @@ -158,7 +158,7 @@ static int sap_write_header(AVFormatContext *s) ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port, "?ttl=%d&connect=1", ttl); - ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE); + ret = ffurl_open(&sap->ann_fd, url, AVIO_WRONLY); if (ret) { ret = AVERROR(EIO); goto fail; diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index ae194d496b..a9b9667d14 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -111,11 +111,16 @@ static int film_read_header(AVFormatContext *s, film->audio_samplerate = AV_RB16(&scratch[24]); film->audio_channels = scratch[21]; film->audio_bits = scratch[22]; - if (film->audio_bits == 8) - film->audio_type = CODEC_ID_PCM_S8; - else if (film->audio_bits == 16) - film->audio_type = CODEC_ID_PCM_S16BE; - else + if (scratch[23] == 2) + film->audio_type = CODEC_ID_ADPCM_ADX; + else if (film->audio_channels > 0) { + if (film->audio_bits == 8) + film->audio_type = CODEC_ID_PCM_S8; + else if (film->audio_bits == 16) + film->audio_type = CODEC_ID_PCM_S16BE; + else + film->audio_type = CODEC_ID_NONE; + } else film->audio_type = CODEC_ID_NONE; } @@ -167,6 +172,8 @@ static int film_read_header(AVFormatContext *s, if(film->sample_count >= UINT_MAX / sizeof(film_sample)) return -1; film->sample_table = av_malloc(film->sample_count * sizeof(film_sample)); + if (!film->sample_table) + return AVERROR(ENOMEM); for(i=0; inb_streams; i++) av_set_pts_info(s->streams[i], 33, 1, film->base_clock); @@ -187,8 +194,12 @@ static int film_read_header(AVFormatContext *s, film->sample_table[i].pts *= film->base_clock; film->sample_table[i].pts /= film->audio_samplerate; - audio_frame_counter += (film->sample_table[i].sample_size / - (film->audio_channels * film->audio_bits / 8)); + if (film->audio_type == CODEC_ID_ADPCM_ADX) + audio_frame_counter += (film->sample_table[i].sample_size * 32 / + (18 * film->audio_channels)); + else if (film->audio_type != CODEC_ID_NONE) + audio_frame_counter += (film->sample_table[i].sample_size / + (film->audio_channels * film->audio_bits / 8)); } else { film->sample_table[i].stream = film->video_stream_index; film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF; @@ -238,6 +249,10 @@ static int film_read_packet(AVFormatContext *s, av_free(film->stereo_buffer); film->stereo_buffer_size = sample->sample_size; film->stereo_buffer = av_malloc(film->stereo_buffer_size); + if (!film->stereo_buffer) { + film->stereo_buffer_size = 0; + return AVERROR(ENOMEM); + } } pkt->pos= avio_tell(pb); diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 29a66e79fa..6a81a48811 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -251,6 +251,8 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) memcpy(oldpal, pal, 768); size = avio_r8(s->pb); size = size * 4 - 1; + if(size + 1 > frame_size) + return AVERROR_INVALIDDATA; frame_size -= size; frame_size--; sz = 0; @@ -261,8 +263,15 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; } else if(t & 0x40){ /* copy with offset */ - off = avio_r8(s->pb) * 3; + off = avio_r8(s->pb); j = (t & 0x3F) + 1; + if (off + j - 1 > 0xff) { + av_log(s, AV_LOG_ERROR, + "Invalid palette update, offset=%d length=%d extends beyond palette size\n", + off, j); + return AVERROR_INVALIDDATA; + } + off *= 3; while(j-- && sz < 256) { *pal++ = oldpal[off + 0]; *pal++ = oldpal[off + 1]; @@ -285,12 +294,19 @@ 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) { - int size; + unsigned int size; + uint8_t *tmpbuf; + size = avio_rl32(s->pb) - 4; + if(size + 4LL > frame_size) + return AVERROR_INVALIDDATA; frame_size -= size; frame_size -= 4; smk->curstream++; - smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size); + tmpbuf = av_realloc(smk->bufs[smk->curstream], size); + if (!tmpbuf) + return AVERROR(ENOMEM); + smk->bufs[smk->curstream] = tmpbuf; smk->buf_sizes[smk->curstream] = size; ret = avio_read(s->pb, smk->bufs[smk->curstream], size); if(ret != size) @@ -299,7 +315,9 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) } flags >>= 1; } - if (av_new_packet(pkt, frame_size + 768)) + if (frame_size < 0) + return AVERROR_INVALIDDATA; + if (av_new_packet(pkt, frame_size + 769)) return AVERROR(ENOMEM); if(smk->frm_size[smk->cur_frame] & 1) palchange |= 2; diff --git a/libavformat/sol.c b/libavformat/sol.c index c0d2c5d5a2..e22207515b 100644 --- a/libavformat/sol.c +++ b/libavformat/sol.c @@ -132,6 +132,8 @@ static int sol_read_packet(AVFormatContext *s, if (url_feof(s->pb)) return AVERROR(EIO); ret= av_get_packet(s->pb, pkt, MAX_SIZE); + if (ret < 0) + return ret; pkt->stream_index = 0; /* note: we need to modify the packet size here to handle the last diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index f90564f3db..f47ad7a8c6 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -84,7 +84,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) SWFContext *swf = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst = NULL, *ast = NULL, *st = 0; - int tag, len, i, frame, v; + int tag, len, i, frame, v, res; for(;;) { uint64_t pos = avio_tell(pb); @@ -147,7 +147,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { frame = avio_rl16(pb); - av_get_packet(pb, pkt, len-2); + if ((res = av_get_packet(pb, pkt, len-2)) < 0) + return res; pkt->pos = pos; pkt->pts = frame; pkt->stream_index = st->index; @@ -160,9 +161,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) { if (st->codec->codec_id == CODEC_ID_MP3) { avio_skip(pb, 4); - av_get_packet(pb, pkt, len-4); + if ((res = av_get_packet(pb, pkt, len-4)) < 0) + return res; } else { // ADPCM, PCM - av_get_packet(pb, pkt, len); + if ((res = av_get_packet(pb, pkt, len)) < 0) + return res; } pkt->pos = pos; pkt->stream_index = st->index; @@ -186,7 +189,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = vst; } avio_rl16(pb); /* BITMAP_ID */ - av_new_packet(pkt, len-2); + if ((res = av_new_packet(pkt, len-2)) < 0) + return res; avio_read(pb, pkt->data, 4); if (AV_RB32(pkt->data) == 0xffd8ffd9 || AV_RB32(pkt->data) == 0xffd9ffd8) { diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c index 09c2d61f28..7d7daacee1 100644 --- a/libavformat/swfenc.c +++ b/libavformat/swfenc.c @@ -498,8 +498,10 @@ static int swf_write_trailer(AVFormatContext *s) avio_wl32(pb, file_size); avio_seek(pb, swf->duration_pos, SEEK_SET); avio_wl16(pb, swf->video_frame_number); + if (swf->vframes_pos) { avio_seek(pb, swf->vframes_pos, SEEK_SET); avio_wl16(pb, swf->video_frame_number); + } avio_seek(pb, file_size, SEEK_SET); } return 0; diff --git a/libavformat/tcp.c b/libavformat/tcp.c index eb982d5675..9b344ab98f 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -68,7 +68,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) snprintf(portstr, sizeof(portstr), "%d", port); ret = getaddrinfo(hostname, portstr, &hints, &ai); if (ret) { - av_log(h, AV_LOG_ERROR, + av_log(NULL, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", hostname, gai_strerror(ret)); return AVERROR(EIO); @@ -128,7 +128,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) optlen = sizeof(ret); getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); if (ret != 0) { - av_log(h, AV_LOG_ERROR, + av_log(NULL, AV_LOG_ERROR, "TCP connection to %s:%d failed: %s\n", hostname, port, strerror(ret)); ret = AVERROR(ret); diff --git a/libavformat/thp.c b/libavformat/thp.c index 2d1f74e38b..ec2bb18076 100644 --- a/libavformat/thp.c +++ b/libavformat/thp.c @@ -174,6 +174,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 c37039d0da..9df9763c74 100644 --- a/libavformat/tta.c +++ b/libavformat/tta.c @@ -107,6 +107,10 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap) return -1; } st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); + if (!st->codec->extradata) { + st->codec->extradata_size = 0; + return AVERROR(ENOMEM); + } avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); diff --git a/libavformat/udp.c b/libavformat/udp.c index 7c18fb7bf0..867339c88d 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -280,7 +280,7 @@ int ff_udp_set_remote_url(URLContext *h, const char *uri) if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) { s->is_connected = 0; - av_log(h, AV_LOG_ERROR, "connect: %s\n", strerror(errno)); + av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno)); return AVERROR(EIO); } } @@ -306,7 +306,10 @@ int ff_udp_get_local_port(URLContext *h) * streams at the same time. * @param h media file context */ -static int udp_get_file_handle(URLContext *h) +#if !FF_API_UDP_GET_FILE +static +#endif +int udp_get_file_handle(URLContext *h) { UDPContext *s = h->priv_data; return s->udp_fd; @@ -389,7 +392,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) h->is_streamed = 1; h->max_packet_size = 1472; - is_output = !(flags & AVIO_FLAG_READ); + is_output = (flags & AVIO_WRONLY); s = av_mallocz(sizeof(UDPContext)); if (!s) @@ -426,7 +429,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { s->is_connected = strtol(buf, NULL, 10); } - if (av_find_info_tag(buf, sizeof(buf), "buf_size", p)) { + if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) { s->circular_buffer_size = strtol(buf, NULL, 10)*188; } } @@ -437,14 +440,14 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* XXX: fix av_url_split */ if (hostname[0] == '\0' || hostname[0] == '?') { /* only accepts null hostname if input */ - if (!(flags & AVIO_FLAG_READ)) + if (flags & AVIO_WRONLY) goto fail; } else { if (ff_udp_set_remote_url(h, uri) < 0) goto fail; } - if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) + if (s->is_multicast && !(h->flags & AVIO_WRONLY)) s->local_port = port; udp_fd = udp_socket_create(s, &my_addr, &len); if (udp_fd < 0) @@ -461,7 +464,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* the bind is needed to give a port to the socket now */ /* if multicast, try the multicast address bind first */ - if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) { + if (s->is_multicast && !(h->flags & AVIO_WRONLY)) { bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); } /* bind to the local address if not multicast or if the multicast @@ -474,7 +477,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) s->local_port = udp_port(&my_addr, len); if (s->is_multicast) { - if (!(h->flags & AVIO_FLAG_READ)) { + if (h->flags & AVIO_WRONLY) { /* output */ if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) goto fail; @@ -489,7 +492,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* limit the tx buf size to limit latency */ tmp = s->buffer_size; if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { - av_log(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno)); + av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno)); goto fail; } } else { @@ -497,14 +500,14 @@ static int udp_open(URLContext *h, const char *uri, int flags) * avoid losing data on OSes that set this too low by default. */ tmp = s->buffer_size; if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) { - av_log(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno)); + av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno)); } /* make the socket non-blocking */ ff_socket_nonblock(udp_fd, 1); } if (s->is_connected) { if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) { - av_log(h, AV_LOG_ERROR, "connect: %s\n", strerror(errno)); + av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno)); goto fail; } } @@ -597,7 +600,7 @@ static int udp_close(URLContext *h) { UDPContext *s = h->priv_data; - if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) + if (s->is_multicast && !(h->flags & AVIO_WRONLY)) udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); closesocket(s->udp_fd); av_fifo_free(s->fifo); diff --git a/libavformat/utils.c b/libavformat/utils.c index cd90480be6..69765ea2b4 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -118,9 +118,15 @@ static void av_frac_add(AVFrac *f, int64_t incr) } /** head of registered input format linked list */ -static AVInputFormat *first_iformat = NULL; +#if !FF_API_FIRST_FORMAT +static +#endif +AVInputFormat *first_iformat = NULL; /** head of registered output format linked list */ -static AVOutputFormat *first_oformat = NULL; +#if !FF_API_FIRST_FORMAT +static +#endif +AVOutputFormat *first_oformat = NULL; AVInputFormat *av_iformat_next(AVInputFormat *f) { @@ -197,6 +203,14 @@ static int match_format(const char *name, const char *names) return !strcasecmp(name, names); } +#if FF_API_GUESS_FORMAT +AVOutputFormat *guess_format(const char *short_name, const char *filename, + const char *mime_type) +{ + return av_guess_format(short_name, filename, mime_type); +} +#endif + AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type) { @@ -232,6 +246,27 @@ AVOutputFormat *av_guess_format(const char *short_name, const char *filename, return fmt_found; } +#if FF_API_GUESS_FORMAT +AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, + const char *mime_type) +{ + AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type); + + if (fmt) { + AVOutputFormat *stream_fmt; + char stream_format_name[64]; + + snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name); + stream_fmt = av_guess_format(stream_format_name, NULL, NULL); + + if (stream_fmt) + fmt = stream_fmt; + } + + return fmt; +} +#endif + enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, const char *filename, const char *mime_type, enum AVMediaType type){ if(type == AVMEDIA_TYPE_VIDEO){ @@ -263,6 +298,38 @@ AVInputFormat *av_find_input_format(const char *short_name) return NULL; } +#if FF_API_SYMVER && CONFIG_SHARED && HAVE_SYMVER +FF_SYMVER(void, av_destruct_packet_nofree, (AVPacket *pkt), "LIBAVFORMAT_52") +{ + av_destruct_packet_nofree(pkt); +} + +FF_SYMVER(void, av_destruct_packet, (AVPacket *pkt), "LIBAVFORMAT_52") +{ + av_destruct_packet(pkt); +} + +FF_SYMVER(int, av_new_packet, (AVPacket *pkt, int size), "LIBAVFORMAT_52") +{ + return av_new_packet(pkt, size); +} + +FF_SYMVER(int, av_dup_packet, (AVPacket *pkt), "LIBAVFORMAT_52") +{ + return av_dup_packet(pkt); +} + +FF_SYMVER(void, av_free_packet, (AVPacket *pkt), "LIBAVFORMAT_52") +{ + av_free_packet(pkt); +} + +FF_SYMVER(void, av_init_packet, (AVPacket *pkt), "LIBAVFORMAT_52") +{ + av_log(NULL, AV_LOG_WARNING, "Diverting av_*_packet function calls to libavcodec. Recompile to improve performance\n"); + av_init_packet(pkt); +} +#endif int av_get_packet(AVIOContext *s, AVPacket *pkt, int size) { @@ -457,18 +524,30 @@ int av_open_input_stream(AVFormatContext **ic_ptr, opts = convert_format_parameters(ap); if(!ap->prealloced_context) - ic = avformat_alloc_context(); + *ic_ptr = ic = avformat_alloc_context(); else ic = *ic_ptr; if (!ic) { err = AVERROR(ENOMEM); goto fail; } - ic->pb = pb; + if (pb && fmt && fmt->flags & AVFMT_NOFILE) + av_log(ic, AV_LOG_WARNING, "Custom AVIOContext makes no sense and " + "will be ignored with AVFMT_NOFILE format.\n"); + else + ic->pb = pb; - err = avformat_open_input(ic_ptr, filename, fmt, &opts); + if ((err = avformat_open_input(&ic, filename, fmt, &opts)) < 0) + goto fail; + *ic_ptr = ic; + ic->pb = ic->pb ? ic->pb : pb; // don't leak custom pb if it wasn't set above + +#if FF_API_OLD_METADATA + ff_metadata_demux_compat(ic); +#endif fail: + *ic_ptr = ic; av_dict_free(&opts); return err; } @@ -518,13 +597,19 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { int ret, score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0; int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1; + void *buftmp; if (probe_size < offset) { continue; } /* read probe data */ - buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE); + buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE); + if(!buftmp){ + av_free(buf); + return AVERROR(ENOMEM); + } + buf=buftmp; if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) { /* fail if error was not end of file, otherwise, lower score */ if (ret != AVERROR_EOF) { @@ -591,7 +676,8 @@ static int init_input(AVFormatContext *s, const char *filename) if (!s->iformat) return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0); else if (s->iformat->flags & AVFMT_NOFILE) - return AVERROR(EINVAL); + av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and " + "will be ignored with AVFMT_NOFILE format.\n"); return 0; } @@ -599,7 +685,7 @@ static int init_input(AVFormatContext *s, const char *filename) (!s->iformat && (s->iformat = av_probe_input_format(&pd, 0)))) return 0; - if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0) + if ((ret = avio_open(&s->pb, filename, AVIO_RDONLY)) < 0) return ret; if (s->iformat) return 0; @@ -636,7 +722,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma } s->duration = s->start_time = AV_NOPTS_VALUE; - av_strlcpy(s->filename, filename, sizeof(s->filename)); + av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename)); /* allocate private data */ if (s->iformat->priv_data_size > 0) { @@ -729,8 +815,6 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt) continue; } - if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA)) - av_packet_merge_side_data(pkt); st= s->streams[pkt->stream_index]; switch(st->codec->codec_type){ @@ -833,7 +917,10 @@ static void compute_frame_duration(int *pnum, int *pden, AVStream *st, *pnum = st->codec->time_base.num; *pden = st->codec->time_base.den; if (pc && pc->repeat_pict) { - *pnum = (*pnum) * (1 + pc->repeat_pict); + if (*pnum > INT_MAX / (1 + pc->repeat_pict)) + *pden /= 1 + pc->repeat_pict; + else + *pnum *= 1 + pc->repeat_pict; } //If this codec can be interlaced or progressive then we need a parser to compute duration of a packet //Thus if we have no parser in such case leave duration undefined. @@ -983,7 +1070,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, // we take the conservative approach and discard both // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly. if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){ - av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination\n"); + av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %Ld\n", pkt->dts); pkt->dts= pkt->pts= AV_NOPTS_VALUE; } @@ -1016,12 +1103,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 } @@ -1121,7 +1210,8 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (!st->need_parsing || !st->parser) { /* no parsing needed: we just output the packet as is */ /* raw data support */ - *pkt = st->cur_pkt; st->cur_pkt.data= NULL; + *pkt = st->cur_pkt; + st->cur_pkt.data= NULL; compute_pkt_fields(s, st, NULL, pkt); s->cur_st = NULL; if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && @@ -1809,7 +1899,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int //Fallback to old API if new is not implemented but old is //Note the old has somewat different sematics if(s->iformat->read_seek || 1) - return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0)); + return av_seek_frame(s, stream_index, ts, flags | ((uint64_t)ts - min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0)); // try some generic seek like av_seek_frame_generic() but with new ts semantics } @@ -2105,7 +2195,7 @@ static int has_decode_delay_been_guessed(AVStream *st) st->codec_info_nb_frames >= 6 + st->codec->has_b_frames; } -static int try_decode_frame(AVStream *st, AVPacket *avpkt) +static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { int16_t *samples; AVCodec *codec; @@ -2116,7 +2206,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt) codec = avcodec_find_decoder(st->codec->codec_id); if (!codec) return -1; - ret = avcodec_open(st->codec, codec); + ret = avcodec_open2(st->codec, codec, options); if (ret < 0) return ret; } @@ -2224,8 +2314,8 @@ static int get_std_framerate(int i){ * And there are "variable" fps files this needs to detect as well. */ static int tb_unreliable(AVCodecContext *c){ - if( c->time_base.den >= 101L*c->time_base.num - || c->time_base.den < 5L*c->time_base.num + if( c->time_base.den >= 101LL*c->time_base.num + || c->time_base.den < 5LL*c->time_base.num /* || c->codec_tag == AV_RL32("DIVX") || c->codec_tag == AV_RL32("XVID")*/ || c->codec_id == CODEC_ID_MPEG2VIDEO @@ -2235,12 +2325,20 @@ static int tb_unreliable(AVCodecContext *c){ return 0; } +#if FF_API_FORMAT_PARAMETERS int av_find_stream_info(AVFormatContext *ic) +{ + return avformat_find_stream_info(ic, NULL); +} +#endif + +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) { int i, count, ret, read_size, j; AVStream *st; AVPacket pkt1, *pkt; int64_t old_offset = avio_tell(ic->pb); + int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those for(i=0;inb_streams;i++) { AVCodec *codec; @@ -2277,12 +2375,12 @@ int av_find_stream_info(AVFormatContext *ic) /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ if (codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); } } @@ -2380,9 +2478,9 @@ int av_find_stream_info(AVFormatContext *ic) } { int64_t last = st->info->last_dts; - int64_t duration= pkt->dts - last; - if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){ + if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last){ + int64_t duration= pkt->dts - last; double dur= duration * av_q2d(st->time_base); // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) @@ -2392,7 +2490,7 @@ int av_find_stream_info(AVFormatContext *ic) for (i=1; iinfo->duration_error); i++) { int framerate= get_std_framerate(i); int ticks= lrintf(dur*framerate/(1001*12)); - double error= dur - ticks*1001*12/(double)framerate; + double error = dur - (double)ticks*1001*12 / framerate; st->info->duration_error[i] += error*error; } st->info->duration_count++; @@ -2418,7 +2516,7 @@ int av_find_stream_info(AVFormatContext *ic) it takes longer and uses more memory. For MPEG-4, we need to decompress for QuickTime. */ if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)) - try_decode_frame(st, pkt); + try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL); st->codec_info_nb_frames++; count++; @@ -2643,28 +2741,39 @@ void avformat_free_context(AVFormatContext *s) av_free_packet(&st->cur_pkt); } av_dict_free(&st->metadata); - av_free(st->index_entries); - av_free(st->codec->extradata); - av_free(st->codec->subtitle_header); - av_free(st->codec); - av_free(st->priv_data); - av_free(st->info); - av_free(st); + 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); +#if FF_API_OLD_METADATA + av_freep(&st->filename); +#endif + av_freep(&st->priv_data); + av_freep(&st->info); + av_freep(&st); } for(i=s->nb_programs-1; i>=0; i--) { - av_dict_free(&s->programs[i]->metadata); +#if FF_API_OLD_METADATA + av_freep(&s->programs[i]->provider_name); + av_freep(&s->programs[i]->name); +#endif + av_metadata_free(&s->programs[i]->metadata); av_freep(&s->programs[i]->stream_index); av_freep(&s->programs[i]); } av_freep(&s->programs); av_freep(&s->priv_data); while(s->nb_chapters--) { +#if FF_API_OLD_METADATA + av_free(s->chapters[s->nb_chapters]->title); +#endif av_dict_free(&s->chapters[s->nb_chapters]->metadata); - av_free(s->chapters[s->nb_chapters]); + av_freep(&s->chapters[s->nb_chapters]); } av_freep(&s->chapters); - av_dict_free(&s->metadata); - av_freep(&s->streams); + av_metadata_free(&s->metadata); +// av_freep(&s->key); av_free(s); } @@ -2681,6 +2790,13 @@ AVStream *av_new_stream(AVFormatContext *s, int id) { AVStream *st; int i; + +#if FF_API_MAX_STREAMS + if (s->nb_streams >= MAX_STREAMS){ + av_log(s, AV_LOG_ERROR, "Too many streams\n"); + return NULL; + } +#else AVStream **streams; if (s->nb_streams >= INT_MAX/sizeof(*streams)) @@ -2689,6 +2805,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id) if (!streams) return NULL; s->streams = streams; +#endif st = av_mallocz(sizeof(AVStream)); if (!st) @@ -2766,6 +2883,9 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6 return NULL; dynarray_add(&s->chapters, &s->nb_chapters, chapter); } +#if FF_API_OLD_METADATA + av_free(chapter->title); +#endif av_dict_set(&chapter->metadata, "title", title, 0); chapter->id = id; chapter->time_base= time_base; @@ -2942,7 +3062,9 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) ret = AVERROR(EINVAL); goto fail; } - if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){ + if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio) + && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(st->codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio) + ){ av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n"); ret = AVERROR(EINVAL); goto fail; @@ -2988,6 +3110,10 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) } } +#if FF_API_OLD_METADATA + ff_metadata_mux_compat(s); +#endif + /* set muxer identification string */ if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0); @@ -3419,7 +3545,7 @@ void av_dump_format(AVFormatContext *ic, int is_output) { int i; - uint8_t *printed = av_mallocz(ic->nb_streams); + uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL; if (ic->nb_streams && !printed) return; @@ -3492,6 +3618,24 @@ void av_dump_format(AVFormatContext *ic, av_free(printed); } +#if FF_API_PARSE_FRAME_PARAM +#include "libavutil/parseutils.h" + +int parse_image_size(int *width_ptr, int *height_ptr, const char *str) +{ + return av_parse_video_size(width_ptr, height_ptr, str); +} + +int parse_frame_rate(int *frame_rate_num, int *frame_rate_den, const char *arg) +{ + AVRational frame_rate; + int ret = av_parse_video_rate(&frame_rate, arg); + *frame_rate_num= frame_rate.num; + *frame_rate_den= frame_rate.den; + return ret; +} +#endif + int64_t av_gettime(void) { struct timeval tv; @@ -3671,6 +3815,24 @@ void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload, pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, st->time_base); } +#if FF_API_URL_SPLIT +attribute_deprecated +void ff_url_split(char *proto, int proto_size, + char *authorization, int authorization_size, + char *hostname, int hostname_size, + int *port_ptr, + char *path, int path_size, + const char *url) +{ + av_url_split(proto, proto_size, + authorization, authorization_size, + hostname, hostname_size, + port_ptr, + path, path_size, + url); +} +#endif + void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, diff --git a/libavformat/version.h b/libavformat/version.h index 691f9c0569..24e247aa19 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -23,8 +23,8 @@ #include "libavutil/avutil.h" -#define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 4 +#define LIBAVFORMAT_VERSION_MAJOR 52 +#define LIBAVFORMAT_VERSION_MINOR 111 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -41,15 +41,60 @@ * Those FF_API_* defines are not part of public API. * They may change, break or disappear at any time. */ +#ifndef FF_API_MAX_STREAMS +#define FF_API_MAX_STREAMS (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_OLD_METADATA +#define FF_API_OLD_METADATA (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif #ifndef FF_API_OLD_METADATA2 #define FF_API_OLD_METADATA2 (LIBAVFORMAT_VERSION_MAJOR < 54) #endif +#ifndef FF_API_URL_CLASS +#define FF_API_URL_CLASS (LIBAVFORMAT_VERSION_MAJOR >= 53) +#endif +#ifndef FF_API_URL_RESETBUF +#define FF_API_URL_RESETBUF (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_REGISTER_PROTOCOL +#define FF_API_REGISTER_PROTOCOL (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_GUESS_FORMAT +#define FF_API_GUESS_FORMAT (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_UDP_GET_FILE +#define FF_API_UDP_GET_FILE (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_URL_SPLIT +#define FF_API_URL_SPLIT (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_ALLOC_FORMAT_CONTEXT +#define FF_API_ALLOC_FORMAT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_PARSE_FRAME_PARAM +#define FF_API_PARSE_FRAME_PARAM (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif #ifndef FF_API_READ_SEEK #define FF_API_READ_SEEK (LIBAVFORMAT_VERSION_MAJOR < 54) #endif +#ifndef FF_API_LAVF_UNUSED +#define FF_API_LAVF_UNUSED (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_PARAMETERS_CODEC_ID +#define FF_API_PARAMETERS_CODEC_ID (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_FIRST_FORMAT +#define FF_API_FIRST_FORMAT (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif +#ifndef FF_API_SYMVER +#define FF_API_SYMVER (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif #ifndef FF_API_OLD_AVIO #define FF_API_OLD_AVIO (LIBAVFORMAT_VERSION_MAJOR < 54) #endif +#ifndef FF_API_INDEX_BUILT +#define FF_API_INDEX_BUILT (LIBAVFORMAT_VERSION_MAJOR < 53) +#endif #ifndef FF_API_DUMP_FORMAT #define FF_API_DUMP_FORMAT (LIBAVFORMAT_VERSION_MAJOR < 54) #endif diff --git a/libavformat/vqf.c b/libavformat/vqf.c index e06f39349b..884611b8e4 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -227,7 +227,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/westwood.c b/libavformat/westwood.c index 818fe2d8d3..dd6ddef905 100644 --- a/libavformat/westwood.c +++ b/libavformat/westwood.c @@ -277,10 +277,8 @@ static int wsvqa_read_header(AVFormatContext *s, /* there are 0 or more chunks before the FINF chunk; iterate until * FINF has been skipped and the file will be ready to be demuxed */ do { - if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { - av_free(st->codec->extradata); + if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) return AVERROR(EIO); - } chunk_tag = AV_RB32(&scratch[0]); chunk_size = AV_RB32(&scratch[4]); diff --git a/libavformat/wv.c b/libavformat/wv.c index 9da416e580..b2b1eb3c62 100644 --- a/libavformat/wv.c +++ b/libavformat/wv.c @@ -110,6 +110,9 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb, int appen size = wc->blksize; } wc->flags = AV_RL32(wc->extra + 4); + // blocks with zero samples don't contain actual audio information and should be ignored + if (!AV_RN32(wc->extra)) + return 0; //parse flags bpp = ((wc->flags & 3) + 1) << 3; chan = 1 + !(wc->flags & WV_MONO); @@ -207,8 +210,14 @@ static int wv_read_header(AVFormatContext *s, AVStream *st; wc->block_parsed = 0; - if(wv_read_block_header(s, pb, 0) < 0) - return -1; + for(;;){ + if(wv_read_block_header(s, pb, 0) < 0) + return -1; + if(!AV_RN32(wc->extra)) + avio_skip(pb, wc->blksize - 24); + else + break; + } /* now we are ready: build format streams */ st = av_new_stream(s, 0); diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c index 90b222d1d4..2fd8c2c5d2 100644 --- a/libavformat/yuv4mpeg.c +++ b/libavformat/yuv4mpeg.c @@ -155,9 +155,8 @@ static int yuv4_write_header(AVFormatContext *s) return AVERROR(EIO); if (s->streams[0]->codec->codec_id != CODEC_ID_RAWVIDEO) { - av_log(s, AV_LOG_ERROR, - "A non-rawvideo stream was selected, but yuv4mpeg only handles rawvideo streams\n"); - return AVERROR(EINVAL); + av_log(s, AV_LOG_ERROR, "ERROR: Only rawvideo supported.\n"); + return AVERROR_INVALIDDATA; } if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) { @@ -353,7 +352,7 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) { int i; char header[MAX_FRAME_HEADER+1]; - int packet_size, width, height; + int packet_size, width, height, ret; AVStream *st = s->streams[0]; struct frame_attributes *s1 = s->priv_data; @@ -364,18 +363,28 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) break; } } - if (i == MAX_FRAME_HEADER) return -1; - if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1; + if (s->pb->error) + return s->pb->error; + else if (s->pb->eof_reached) + return AVERROR_EOF; + else if (i == MAX_FRAME_HEADER) + return AVERROR_INVALIDDATA; + + if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) + return AVERROR_INVALIDDATA; width = st->codec->width; height = st->codec->height; packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); if (packet_size < 0) - return -1; + return packet_size; - if (av_get_packet(s->pb, pkt, packet_size) != packet_size) - return AVERROR(EIO); + ret = av_get_packet(s->pb, pkt, packet_size); + if (ret < 0) + return ret; + else if (ret != packet_size) + return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO); if (s->streams[0]->codec->coded_frame) { s->streams[0]->codec->coded_frame->interlaced_frame = s1->interlaced_frame; diff --git a/libavutil/Makefile b/libavutil/Makefile index 0d8f01dd8d..f6f5fd3b91 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -36,6 +36,7 @@ HEADERS = adler32.h \ rational.h \ samplefmt.h \ sha.h \ + sha1.h \ BUILT_HEADERS = avconfig.h diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h index 4130177549..1e9d3e8b15 100644 --- a/libavutil/arm/intmath.h +++ b/libavutil/arm/intmath.h @@ -104,7 +104,7 @@ static av_always_inline av_const int32_t av_clipl_int32_arm(int64_t a) "mvnne %1, #1<<31 \n\t" "moveq %0, %Q2 \n\t" "eorne %0, %1, %R2, asr #31 \n\t" - : "=r"(x), "=&r"(y) : "r"(a)); + : "=r"(x), "=&r"(y) : "r"(a):"cc"); return x; } diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 4d6ef66003..59b59db29e 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -39,9 +39,9 @@ #define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) -#define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 9 -#define LIBAVUTIL_VERSION_MICRO 1 +#define LIBAVUTIL_VERSION_MAJOR 50 +#define LIBAVUTIL_VERSION_MINOR 43 +#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ @@ -59,6 +59,7 @@ */ #ifndef FF_API_OLD_EVAL_NAMES #define FF_API_OLD_EVAL_NAMES (LIBAVUTIL_VERSION_MAJOR < 52) + #endif #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT #define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52) @@ -103,8 +104,16 @@ enum AVMediaType { #define AV_TIME_BASE 1000000 #define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} +/** + * Those FF_API_* defines are not part of public API. + * They may change, break or disappear at any time. + */ +#ifndef FF_API_OLD_IMAGE_NAMES +#define FF_API_OLD_IMAGE_NAMES (LIBAVUTIL_VERSION_MAJOR < 51) +#endif enum AVPictureType { - AV_PICTURE_TYPE_I = 1, ///< Intra + AV_PICTURE_TYPE_NONE = 0, ///< Undefined + AV_PICTURE_TYPE_I, ///< Intra AV_PICTURE_TYPE_P, ///< Predicted AV_PICTURE_TYPE_B, ///< Bi-dir predicted AV_PICTURE_TYPE_S, ///< S(GMC)-VOP MPEG4 diff --git a/libavutil/crc.c b/libavutil/crc.c index c3d74a2ce9..d0e736ed4d 100644 --- a/libavutil/crc.c +++ b/libavutil/crc.c @@ -57,7 +57,7 @@ static AVCRC av_crc_table[AV_CRC_MAX][257]; * @return <0 on failure */ int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){ - int i, j; + unsigned i, j; uint32_t c; if (bits < 8 || bits > 32 || poly >= (1LL< 50 +#define AVERROR_INVALIDDATA (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input +#define AVERROR_NUMEXPECTED (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename +#endif + +#define AVERROR_DEMUXER_NOT_FOUND (-MKTAG(0xF8,'D','E','M')) ///< Demuxer not found +#define AVERROR_MUXER_NOT_FOUND (-MKTAG(0xF8,'M','U','X')) ///< Muxer not found + #define AVERROR_BSF_NOT_FOUND (-MKTAG(0xF8,'B','S','F')) ///< Bitstream filter not found #define AVERROR_DECODER_NOT_FOUND (-MKTAG(0xF8,'D','E','C')) ///< Decoder not found #define AVERROR_DEMUXER_NOT_FOUND (-MKTAG(0xF8,'D','E','M')) ///< Demuxer not found #define AVERROR_ENCODER_NOT_FOUND (-MKTAG(0xF8,'E','N','C')) ///< Encoder not found -#define AVERROR_EOF (-MKTAG( 'E','O','F',' ')) ///< End of file #define AVERROR_EXIT (-MKTAG( 'E','X','I','T')) ///< Immediate exit was requested; the called function should not be restarted #define AVERROR_FILTER_NOT_FOUND (-MKTAG(0xF8,'F','I','L')) ///< Filter not found -#define AVERROR_INVALIDDATA (-MKTAG( 'I','N','D','A')) ///< Invalid data found when processing input #define AVERROR_MUXER_NOT_FOUND (-MKTAG(0xF8,'M','U','X')) ///< Muxer not found #define AVERROR_OPTION_NOT_FOUND (-MKTAG(0xF8,'O','P','T')) ///< Option not found -#define AVERROR_PATCHWELCOME (-MKTAG( 'P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome #define AVERROR_PROTOCOL_NOT_FOUND (-MKTAG(0xF8,'P','R','O')) ///< Protocol not found #define AVERROR_STREAM_NOT_FOUND (-MKTAG(0xF8,'S','T','R')) ///< Stream not found diff --git a/libavutil/eval.c b/libavutil/eval.c index fa2999b84c..7d757e08fa 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -279,8 +279,8 @@ static int parse_primary(AVExpr **e, Parser *p) else if (strmatch(next, "eq" )) d->type = e_eq; else if (strmatch(next, "gte" )) d->type = e_gte; else if (strmatch(next, "gt" )) d->type = e_gt; - else if (strmatch(next, "lte" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; } - else if (strmatch(next, "lt" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; } + else if (strmatch(next, "lte" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; } + else if (strmatch(next, "lt" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; } else if (strmatch(next, "ld" )) d->type = e_ld; else if (strmatch(next, "isnan" )) d->type = e_isnan; else if (strmatch(next, "st" )) d->type = e_st; @@ -499,6 +499,7 @@ int av_expr_parse(AVExpr **expr, const char *s, if ((ret = parse_expr(&e, &p)) < 0) goto end; if (*p.s) { + av_expr_free(e); av_log(&p, AV_LOG_ERROR, "Invalid chars '%s' at the end of expression '%s'\n", p.s, s0); ret = AVERROR(EINVAL); goto end; diff --git a/libavutil/file.c b/libavutil/file.c index ed6fa38b9c..0704080c5b 100644 --- a/libavutil/file.c +++ b/libavutil/file.c @@ -47,6 +47,7 @@ int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, av_unused void *ptr; off_t off_size; char errbuf[128]; + size_t max_size = HAVE_MMAP ? SIZE_MAX : FF_INTERNAL_MEM_TYPE_MAX_VALUE; *bufptr = NULL; if (fd < 0) { @@ -65,7 +66,7 @@ int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, } off_size = st.st_size; - if (off_size > SIZE_MAX) { + if (off_size > max_size) { av_log(&file_log_ctx, AV_LOG_ERROR, "File size for file '%s' is too big\n", filename); close(fd); diff --git a/libavutil/file.h b/libavutil/file.h index f94d7803f1..f28627c9d8 100644 --- a/libavutil/file.h +++ b/libavutil/file.h @@ -22,7 +22,8 @@ #include "avutil.h" /** - * @file misc file utilities + * @file + * Misc file utilities. */ /** diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index e04c307f62..c8ae6648c4 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -125,7 +125,7 @@ int av_image_fill_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int heigh has_plane[desc->comp[i].plane] = 1; total_size = size[0]; - for (i = 1; has_plane[i] && i < 4; i++) { + for (i = 1; i < 4 && has_plane[i]; i++) { int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; data[i] = data[i-1] + size[i-1]; h = (height + (1 << s) - 1) >> s; @@ -274,3 +274,32 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], } } } + +#if FF_API_OLD_IMAGE_NAMES +void av_fill_image_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc) +{ + av_image_fill_max_pixsteps(max_pixsteps, max_pixstep_comps, pixdesc); +} + +int av_get_image_linesize(enum PixelFormat pix_fmt, int width, int plane) +{ + return av_image_get_linesize(pix_fmt, width, plane); +} + +int av_fill_image_linesizes(int linesizes[4], enum PixelFormat pix_fmt, int width) +{ + return av_image_fill_linesizes(linesizes, pix_fmt, width); +} + +int av_fill_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]) +{ + return av_image_fill_pointers(data, pix_fmt, height, ptr, linesizes); +} + +int av_check_image_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx) +{ + return av_image_check_size(w, h, log_offset, log_ctx); +} +#endif diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index f34cb2d921..3a738c1490 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -69,7 +69,7 @@ int av_image_fill_linesizes(int linesizes[4], enum PixelFormat pix_fmt, int widt * * @param data pointers array to be filled with the pointer for each image plane * @param ptr the pointer to a buffer which will contain the image - * @param linesizes[4] the array containing the linesize for each + * @param linesizes the array containing the linesize for each * plane, should be filled by av_image_fill_linesizes() * @return the size in bytes required for the image buffer, a negative * error code in case of failure @@ -127,4 +127,23 @@ int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *lo int ff_set_systematic_pal2(uint32_t pal[256], enum PixelFormat pix_fmt); +#if FF_API_OLD_IMAGE_NAMES +attribute_deprecated +void av_fill_image_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc); + +attribute_deprecated +int av_get_image_linesize(enum PixelFormat pix_fmt, int width, int plane); + +attribute_deprecated +int av_fill_image_linesizes(int linesizes[4], enum PixelFormat pix_fmt, int width); + +attribute_deprecated +int av_fill_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]); + +attribute_deprecated +int av_check_image_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx); +#endif + #endif /* AVUTIL_IMGUTILS_H */ diff --git a/libavutil/intfloat_readwrite.c b/libavutil/intfloat_readwrite.c index f51d8ddd4f..991aa7886c 100644 --- a/libavutil/intfloat_readwrite.c +++ b/libavutil/intfloat_readwrite.c @@ -30,13 +30,13 @@ #include "intfloat_readwrite.h" double av_int2dbl(int64_t v){ - if(v+v > 0xFFEULL<<52) + if((uint64_t)v+v > 0xFFEULL<<52) return NAN; return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075); } float av_int2flt(int32_t v){ - if(v+v > 0xFF000000U) + if((uint32_t)v+v > 0xFF000000U) return NAN; return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150); } diff --git a/libavutil/lfg.h b/libavutil/lfg.h index 0e89ea308d..854ffce737 100644 --- a/libavutil/lfg.h +++ b/libavutil/lfg.h @@ -55,7 +55,7 @@ static inline unsigned int av_mlfg_get(AVLFG *c){ * Get the next two numbers generated by a Box-Muller Gaussian * generator using the random numbers issued by lfg. * - * @param out[2] array where the two generated numbers are placed + * @param out array where the two generated numbers are placed */ void av_bmg_get(AVLFG *lfg, double out[2]); diff --git a/libavutil/log.c b/libavutil/log.c index fd5e2cbbe2..4e9cfe9c01 100644 --- a/libavutil/log.c +++ b/libavutil/log.c @@ -29,7 +29,10 @@ #include "avutil.h" #include "log.h" -static int av_log_level = AV_LOG_INFO; +#if LIBAVUTIL_VERSION_MAJOR > 50 +static +#endif +int av_log_level = AV_LOG_INFO; static int flags; #if defined(_WIN32) && !defined(__MINGW32CE__) @@ -100,7 +103,7 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) line[0]=0; #undef fprintf if(print_prefix && avc) { - if (avc->parent_log_context_offset) { + if(avc->version >= (50<<16 | 15<<8 | 3) && avc->parent_log_context_offset){ AVClass** parent= *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset); if(parent && *parent){ snprintf(line, sizeof(line), "[%s @ %p] ", (*parent)->item_name(parent), parent); diff --git a/libavutil/lzo.c b/libavutil/lzo.c index 40a41a424d..d91fbfc6a6 100644 --- a/libavutil/lzo.c +++ b/libavutil/lzo.c @@ -62,7 +62,13 @@ static inline int get_byte(LZOContext *c) { static inline int get_len(LZOContext *c, int x, int mask) { int cnt = x & mask; if (!cnt) { - while (!(x = get_byte(c))) cnt += 255; + while (!(x = get_byte(c))) { + if (cnt >= INT_MAX - 1000) { + c->error |= AV_LZO_ERROR; + break; + } + cnt += 255; + } cnt += mask + x; } return cnt; @@ -119,9 +125,8 @@ static inline void memcpy_backptr(uint8_t *dst, int back, int cnt); * thus creating a repeating pattern with a period length of back. */ static inline void copy_backptr(LZOContext *c, int back, int cnt) { - register const uint8_t *src = &c->out[-back]; register uint8_t *dst = c->out; - if (src < c->out_start || src > dst) { + if (dst - c->out_start < back) { c->error |= AV_LZO_INVALID_BACKPTR; return; } @@ -175,11 +180,11 @@ int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen) { int state= 0; int x; LZOContext c; - if (!*outlen || !*inlen) { + if (*outlen <= 0 || *inlen <= 0) { int res = 0; - if (!*outlen) + if (*outlen <= 0) res |= AV_LZO_OUTPUT_FULL; - if (!*inlen) + if (*inlen <= 0) res |= AV_LZO_INPUT_DEPLETED; return res; } diff --git a/libavutil/lzo.h b/libavutil/lzo.h index 6788054bff..7fa3bd2f83 100644 --- a/libavutil/lzo.h +++ b/libavutil/lzo.h @@ -24,7 +24,7 @@ #include -/** \defgroup errflags Error flags returned by av_lzo1x_decode +/** @name Error flags returned by av_lzo1x_decode * \{ */ //! end of the input buffer reached before decoding finished #define AV_LZO_INPUT_DEPLETED 1 diff --git a/libavutil/mem.c b/libavutil/mem.c index 87c2008a27..9916234c3d 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -67,7 +67,7 @@ void free(void *ptr); #define MAX_MALLOC_SIZE INT_MAX -void *av_malloc(size_t size) +void *av_malloc(FF_INTERNAL_MEM_TYPE size) { void *ptr = NULL; #if CONFIG_MEMALIGN_HACK @@ -123,7 +123,7 @@ void *av_malloc(size_t size) return ptr; } -void *av_realloc(void *ptr, size_t size) +void *av_realloc(void *ptr, FF_INTERNAL_MEM_TYPE size) { #if CONFIG_MEMALIGN_HACK int diff; @@ -137,12 +137,29 @@ void *av_realloc(void *ptr, size_t size) //FIXME this isn't aligned correctly, though it probably isn't needed if(!ptr) return av_malloc(size); diff= ((char*)ptr)[-1]; - return (char*)realloc((char*)ptr - diff, size + diff) + diff; + ptr= realloc((char*)ptr - diff, size + diff); + if(ptr) ptr = (char*)ptr + diff; + return ptr; #else return realloc(ptr, size + !size); #endif } +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize) +{ + size_t size; + void *r; + + if (av_size_mult(elsize, nelem, &size)) { + av_free(ptr); + return NULL; + } + r = av_realloc(ptr, size); + if (!r && size) + av_free(ptr); + return r; +} + void av_free(void *ptr) { #if CONFIG_MEMALIGN_HACK @@ -160,7 +177,7 @@ void av_freep(void *arg) *ptr = NULL; } -void *av_mallocz(size_t size) +void *av_mallocz(FF_INTERNAL_MEM_TYPE size) { void *ptr = av_malloc(size); if (ptr) @@ -168,6 +185,13 @@ void *av_mallocz(size_t size) return ptr; } +void *av_calloc(size_t nmemb, size_t size) +{ + if (size <= 0 || nmemb >= INT_MAX / size) + return NULL; + return av_mallocz(nmemb * size); +} + char *av_strdup(const char *s) { char *ptr= NULL; diff --git a/libavutil/mem.h b/libavutil/mem.h index 7c30e160fb..95e776a8a5 100644 --- a/libavutil/mem.h +++ b/libavutil/mem.h @@ -27,6 +27,7 @@ #define AVUTIL_MEM_H #include "attributes.h" +#include "error.h" #include "avutil.h" #if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) @@ -62,6 +63,14 @@ #define av_alloc_size(n) #endif +#if LIBAVUTIL_VERSION_MAJOR < 51 +# define FF_INTERNAL_MEM_TYPE unsigned int +# define FF_INTERNAL_MEM_TYPE_MAX_VALUE UINT_MAX +#else +# define FF_INTERNAL_MEM_TYPE size_t +# define FF_INTERNAL_MEM_TYPE_MAX_VALUE SIZE_MAX +#endif + /** * Allocate a block of size bytes with alignment suitable for all * memory accesses (including vectors if available on the CPU). @@ -70,7 +79,7 @@ * be allocated. * @see av_mallocz() */ -void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); +void *av_malloc(FF_INTERNAL_MEM_TYPE size) av_malloc_attrib av_alloc_size(1); /** * Allocate or reallocate a block of memory. @@ -84,7 +93,17 @@ void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); * cannot be reallocated or the function is used to free the memory block. * @see av_fast_realloc() */ -void *av_realloc(void *ptr, size_t size) av_alloc_size(2); +void *av_realloc(void *ptr, FF_INTERNAL_MEM_TYPE size) av_alloc_size(2); + +/** + * Allocate or reallocate a block of memory. + * This function does the same thing as av_realloc, except: + * - It takes two arguments and checks the result of the multiplication for + * integer overflow. + * - It frees the input block in case of failure, thus avoiding the memory + * leak with the classic "buf = realloc(buf); if (!buf) return -1;". + */ +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize); /** * Free a memory block which has been allocated with av_malloc(z)() or @@ -104,7 +123,19 @@ void av_free(void *ptr); * @return Pointer to the allocated block, NULL if it cannot be allocated. * @see av_malloc() */ -void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); +void *av_mallocz(FF_INTERNAL_MEM_TYPE size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a block of nmemb * size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU) and + * zero all the bytes of the block. + * The allocation will fail if nmemb * size is greater than or equal + * to INT_MAX. + * @param nmemb + * @param size + * @return Pointer to the allocated block, NULL if it cannot be allocated. + */ +void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib; /** * Duplicate the string s. @@ -132,4 +163,19 @@ void av_freep(void *ptr); */ void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem); +/** + * Multiply two size_t values checking for overflow. + * @return 0 if success, AVERROR(EINVAL) if overflow. + */ +static inline int av_size_mult(size_t a, size_t b, size_t *r) +{ + size_t t = a * b; + /* Hack inspired from glibc: only try the division if nelem and elsize + * are both greater than sqrt(SIZE_MAX). */ + if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) + return AVERROR(EINVAL); + *r = t; + return 0; +} + #endif /* AVUTIL_MEM_H */ diff --git a/libavutil/opt.h b/libavutil/opt.h index 68873de563..10a67912e5 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -134,7 +134,7 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m * when 0 then no av_free() nor av_strdup() will be used * @return 0 if the value has been set, or an AVERROR code in case of * error: - * AVERROR(ENOENT) if no matching option exists + * AVERROR_OPTION_NOT_FOUND if no matching option exists * AVERROR(ERANGE) if the value is out of range * AVERROR(EINVAL) if the value is not valid */ diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 491955a020..8a19be1702 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -918,9 +918,9 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = { .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { - {0,1,1,0,9}, /* Y */ - {1,1,1,0,9}, /* U */ - {2,1,1,0,9}, /* V */ + {0,1,1,0,8}, /* Y */ + {1,1,1,0,8}, /* U */ + {2,1,1,0,8}, /* V */ }, .flags = PIX_FMT_BE, }, diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c index 6d19b1a9fe..db1ba39cf2 100644 --- a/libavutil/random_seed.c +++ b/libavutil/random_seed.c @@ -80,3 +80,11 @@ uint32_t av_get_random_seed(void) return seed; return get_generic_seed(); } + +#if LIBAVUTIL_VERSION_MAJOR < 51 +attribute_deprecated uint32_t ff_random_get_seed(void); +uint32_t ff_random_get_seed(void) +{ + return av_get_random_seed(); +} +#endif diff --git a/libavutil/sha.c b/libavutil/sha.c index ff9e55720f..2657f7eb90 100644 --- a/libavutil/sha.c +++ b/libavutil/sha.c @@ -25,6 +25,7 @@ #include "avutil.h" #include "bswap.h" #include "sha.h" +#include "sha1.h" #include "intreadwrite.h" /** hash context */ @@ -323,6 +324,29 @@ void av_sha_final(AVSHA* ctx, uint8_t *digest) AV_WB32(digest + i*4, ctx->state[i]); } +#if LIBAVUTIL_VERSION_MAJOR < 51 +struct AVSHA1 { + AVSHA sha; +}; + +const int av_sha1_size = sizeof(struct AVSHA1); + +void av_sha1_init(struct AVSHA1* context) +{ + av_sha_init(&context->sha, 160); +} + +void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len) +{ + av_sha_update(&context->sha, data, len); +} + +void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]) +{ + av_sha_final(&context->sha, digest); +} +#endif + #ifdef TEST #include #undef printf diff --git a/libavutil/sha1.h b/libavutil/sha1.h new file mode 100644 index 0000000000..3ff58043ea --- /dev/null +++ b/libavutil/sha1.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SHA1_H +#define AVUTIL_SHA1_H + +#include + +extern const int av_sha1_size; + +struct AVSHA1; + +/** + * Initialize SHA-1 hashing. + * + * @param context pointer to the function context (of size av_sha_size) + * @deprecated use av_sha_init() instead + */ +void av_sha1_init(struct AVSHA1* context); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + * @deprecated use av_sha_update() instead + */ +void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len); + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + * @deprecated use av_sha_final() instead + */ +void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]); + +#endif /* AVUTIL_SHA1_H */ diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index 2cefdbfbe5..711d5d4097 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -113,7 +113,7 @@ int ff_get_cpu_flags_x86(void) if(max_ext_level >= 0x80000001){ cpuid(0x80000001, eax, ebx, ecx, ext_caps); - if (ext_caps & (1<<31)) + if (ext_caps & (1U<<31)) rval |= AV_CPU_FLAG_3DNOW; if (ext_caps & (1<<30)) rval |= AV_CPU_FLAG_3DNOWEXT; diff --git a/libswscale/Makefile b/libswscale/Makefile index 8bb06baae2..11017f6580 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -20,6 +20,8 @@ OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \ x86/yuv2rgb_mmx.o OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o +$(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS) + TESTPROGS = colorspace swscale DIRS = bfin mlib ppc sparc x86 diff --git a/libswscale/options.c b/libswscale/options.c index 010c68ecbe..24e70b96fc 100644 --- a/libswscale/options.c +++ b/libswscale/options.c @@ -20,7 +20,7 @@ #include "libavutil/avutil.h" #include "libavutil/pixfmt.h" -#include "libavutil/opt.h" +#include "libavcodec/opt.h" #include "swscale.h" #include "swscale_internal.h" diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c index 197000beb9..13b21b5b8d 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -251,7 +251,7 @@ static void hScale_altivec_real(int16_t *dst, int dstW, vector unsigned char src_v1, src_vF; vector signed short src_v, filter_v; vector signed int val_vEven, val_s; - if ((((int)src + srcPos)% 16) > 12) { + if ((((uintptr_t)src + srcPos) % 16) > 12) { src_v1 = vec_ld(srcPos + 16, src); } src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); @@ -290,7 +290,7 @@ static void hScale_altivec_real(int16_t *dst, int dstW, vector unsigned char src_v1, src_vF; vector signed short src_v, filter_v; vector signed int val_v, val_s; - if ((((int)src + srcPos)% 16) > 8) { + if ((((uintptr_t)src + srcPos) % 16) > 8) { src_v1 = vec_ld(srcPos + 16, src); } src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); @@ -376,7 +376,7 @@ static void hScale_altivec_real(int16_t *dst, int dstW, //vector unsigned char src_v0 = vec_ld(srcPos + j, src); vector unsigned char src_v1, src_vF; vector signed short src_v, filter_v1R, filter_v; - if ((((int)src + srcPos)% 16) > 8) { + if ((((uintptr_t)src + srcPos) % 16) > 8) { src_v1 = vec_ld(srcPos + j + 16, src); } src_vF = vec_perm(src_v0, src_v1, permS); diff --git a/libswscale/swscale.h b/libswscale/swscale.h index 4bb2dfcf28..e533a366f2 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -29,9 +29,9 @@ #include "libavutil/avutil.h" -#define LIBSWSCALE_VERSION_MAJOR 2 -#define LIBSWSCALE_VERSION_MINOR 0 -#define LIBSWSCALE_VERSION_MICRO 0 +#define LIBSWSCALE_VERSION_MAJOR 0 +#define LIBSWSCALE_VERSION_MINOR 14 +#define LIBSWSCALE_VERSION_MICRO 1 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ @@ -247,7 +247,6 @@ int sws_scale_ordered(struct SwsContext *context, const uint8_t* const src[], /** * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x] - * @param fullRange if 1 then the luma range is 0..255 if 0 it is 16..235 * @return -1 if not supported */ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], @@ -354,7 +353,7 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context, * @param num_pixels number of pixels to convert * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src */ -void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); +void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); /** * Converts an 8bit paletted frame into a frame with a color depth of 24 bits. @@ -366,7 +365,7 @@ void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pix * @param num_pixels number of pixels to convert * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src */ -void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); +void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); #endif /* SWSCALE_SWSCALE_H */ diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index e0c4b25846..e17de2b206 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -182,14 +182,14 @@ static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStrid return srcSliceH; } -static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) +static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) { int i; for (i=0; isrcFormat; const enum PixelFormat dstFormat= c->dstFormat; - void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels, + void (*conv)(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)=NULL; int i; uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; @@ -826,7 +826,7 @@ int sws_scale_ordered(SwsContext *c, const uint8_t* const src[], int srcStride[] #endif /* Convert the palette to the same packed 32-bit format as the palette */ -void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) +void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) { int i; @@ -835,7 +835,7 @@ void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pix } /* Palette format: ABCD -> dst format: ABC */ -void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) +void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) { int i; diff --git a/libswscale/utils.c b/libswscale/utils.c index 984f2c52fa..36bb0fa703 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -44,6 +44,7 @@ #include "libavutil/cpu.h" #include "libavutil/avutil.h" #include "libavutil/bswap.h" +#include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -271,7 +272,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi xDstInSrc+= xInc; } } else { - int xDstInSrc; + int64_t xDstInSrc; int sizeFactor; if (flags&SWS_BICUBIC) sizeFactor= 4; @@ -290,7 +291,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW; - if (filterSize > srcW-2) filterSize=srcW-2; + filterSize = av_clip(filterSize, 1, srcW - 2); FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); @@ -823,8 +824,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) if (!dstFilter) dstFilter= &dummyFilter; if (!srcFilter) srcFilter= &dummyFilter; - c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW; - c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH; + c->lumXInc= (((int64_t)srcW<<16) + (dstW>>1))/dstW; + c->lumYInc= (((int64_t)srcH<<16) + (dstH>>1))/dstH; c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]); c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]); c->vRounder= 4* 0x0001000100010001ULL; @@ -886,8 +887,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) else c->canMMX2BeUsed=0; - c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW; - c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH; + c->chrXInc= (((int64_t)c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW; + c->chrYInc= (((int64_t)c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH; // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst // but only for the FAST_BILINEAR mode otherwise do correct scaling @@ -902,8 +903,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) } //we don't use the x86 asm scaler if MMX is available else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { - c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; - c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; + c->lumXInc = ((int64_t)(srcW-2)<<16)/(dstW-2) - 20; + c->chrXInc = ((int64_t)(c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; } } @@ -1007,7 +1008,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) c->vLumBufSize= c->vLumFilterSize; c->vChrBufSize= c->vChrFilterSize; for (i=0; ichrDstH / dstH; + int chrI = (int64_t) i * c->chrDstH / dstH; int nextSlice= FFMAX(c->vLumFilterPos[i ] + c->vLumFilterSize - 1, ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<chrSrcVSubSample)); diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c index baef3f8ae5..bfa0d4fbd6 100644 --- a/libswscale/x86/rgb2rgb_template.c +++ b/libswscale/x86/rgb2rgb_template.c @@ -1971,6 +1971,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_mmx.c b/libswscale/x86/swscale_mmx.c index 775d5f683d..2f54f49f91 100644 --- a/libswscale/x86/swscale_mmx.c +++ b/libswscale/x86/swscale_mmx.c @@ -132,6 +132,44 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; int i; + + if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) { + const int16_t **tmpY = (const int16_t **) lumPixBuf + 2 * vLumBufSize; + int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize); + for (i = 0; i < neg; i++) + tmpY[i] = lumSrcPtr[neg]; + for ( ; i < end; i++) + tmpY[i] = lumSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpY[i] = tmpY[i-1]; + lumSrcPtr = tmpY; + + if (alpSrcPtr) { + const int16_t **tmpA = (const int16_t **) alpPixBuf + 2 * vLumBufSize; + for (i = 0; i < neg; i++) + tmpA[i] = alpSrcPtr[neg]; + for ( ; i < end; i++) + tmpA[i] = alpSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpA[i] = tmpA[i - 1]; + alpSrcPtr = tmpA; + } + } + if (firstChrSrcY < 0 || firstChrSrcY + vChrFilterSize > c->chrSrcH) { + const int16_t **tmpU = (const int16_t **) chrUPixBuf + 2 * vChrBufSize; + int neg = -firstChrSrcY, i, end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize); + for (i = 0; i < neg; i++) { + tmpU[i] = chrUSrcPtr[neg]; + } + for ( ; i < end; i++) { + tmpU[i] = chrUSrcPtr[i]; + } + for ( ; i < vChrFilterSize; i++) { + tmpU[i] = tmpU[i - 1]; + } + chrUSrcPtr = tmpU; + } + if (flags & SWS_ACCURATE_RND) { int s= APCK_SIZE / 8; for (i=0; ilumMmx2FilterCode; int i; #if defined(PIC) - DECLARE_ALIGNED(8, uint64_t, ebxsave); + uint64_t ebxsave; +#endif +#if ARCH_X86_64 + uint64_t retsave; #endif __asm__ volatile( #if defined(PIC) "mov %%"REG_b", %5 \n\t" +#if ARCH_X86_64 + "mov -8(%%rsp), %%"REG_a" \n\t" + "mov %%"REG_a", %6 \n\t" +#endif +#else +#if ARCH_X86_64 + "mov -8(%%rsp), %%"REG_a" \n\t" + "mov %%"REG_a", %5 \n\t" +#endif #endif "pxor %%mm7, %%mm7 \n\t" "mov %0, %%"REG_c" \n\t" @@ -2285,11 +2297,23 @@ static void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, #if defined(PIC) "mov %5, %%"REG_b" \n\t" +#if ARCH_X86_64 + "mov %6, %%"REG_a" \n\t" + "mov %%"REG_a", -8(%%rsp) \n\t" +#endif +#else +#if ARCH_X86_64 + "mov %5, %%"REG_a" \n\t" + "mov %%"REG_a", -8(%%rsp) \n\t" +#endif #endif :: "m" (src), "m" (dst), "m" (filter), "m" (filterPos), "m" (mmx2FilterCode) #if defined(PIC) ,"m" (ebxsave) +#endif +#if ARCH_X86_64 + ,"m"(retsave) #endif : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D #if !defined(PIC) @@ -2312,10 +2336,22 @@ static void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *dst2, #if defined(PIC) DECLARE_ALIGNED(8, uint64_t, ebxsave); #endif +#if ARCH_X86_64 + DECLARE_ALIGNED(8, uint64_t, retsave); +#endif __asm__ volatile( #if defined(PIC) "mov %%"REG_b", %7 \n\t" +#if ARCH_X86_64 + "mov -8(%%rsp), %%"REG_a" \n\t" + "mov %%"REG_a", %8 \n\t" +#endif +#else +#if ARCH_X86_64 + "mov -8(%%rsp), %%"REG_a" \n\t" + "mov %%"REG_a", %7 \n\t" +#endif #endif "pxor %%mm7, %%mm7 \n\t" "mov %0, %%"REG_c" \n\t" @@ -2345,11 +2381,23 @@ static void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *dst2, #if defined(PIC) "mov %7, %%"REG_b" \n\t" +#if ARCH_X86_64 + "mov %8, %%"REG_a" \n\t" + "mov %%"REG_a", -8(%%rsp) \n\t" +#endif +#else +#if ARCH_X86_64 + "mov %7, %%"REG_a" \n\t" + "mov %%"REG_a", -8(%%rsp) \n\t" +#endif #endif :: "m" (src1), "m" (dst1), "m" (filter), "m" (filterPos), "m" (mmx2FilterCode), "m" (src2), "m"(dst2) #if defined(PIC) ,"m" (ebxsave) +#endif +#if ARCH_X86_64 + ,"m"(retsave) #endif : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D #if !defined(PIC) diff --git a/tests/fate.mak b/tests/fate.mak index 0e3331178b..c6550a9a31 100644 --- a/tests/fate.mak +++ b/tests/fate.mak @@ -128,7 +128,7 @@ FATE_TESTS += fate-id-cin-video fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24 FATE_TESTS += fate-idroq-video-dpcm fate-idroq-video-dpcm: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -FATE_TESTS += fate-idroq-video-encode +FATE_TESTS-$(CONFIG_AVFILTER) += fate-idroq-video-encode fate-idroq-video-encode: CMD = md5 -t 0.2 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ FATE_TESTS += fate-iff-byterun1 fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24 @@ -175,7 +175,7 @@ fate-maxis-xa: CMD = md5 -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -f s16le FATE_TESTS += fate-mimic fate-mimic: CMD = framecrc -idct simple -i $(SAMPLES)/mimic/mimic2-womanloveffmpeg.cam -vsync 0 FATE_TESTS += fate-motionpixels -fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 +fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111 FATE_TESTS += fate-mpc7-demux fate-mpc7-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp7.mpc -acodec copy FATE_TESTS += fate-mpc8-demux diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 39e752b3c6..07dedb2ef2 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -66,6 +66,9 @@ fi if [ -n "$do_mxf" ] ; then do_lavf mxf "-ar 48000 -bf 2 -timecode_frame_start 264363" +fi + +if [ -n "$do_mxf_d10" ]; then do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec mpeg2video -intra -flags +ildct+low_delay -dc 10 -flags2 +ivlc+non_linear_q -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10" fi diff --git a/tests/ref/acodec/alac b/tests/ref/acodec/alac index 1f4b264b87..35a1d8e1bf 100644 --- a/tests/ref/acodec/alac +++ b/tests/ref/acodec/alac @@ -1,4 +1,4 @@ -c68f649777ab8e7c9a0f1f221451d3ad *./tests/data/acodec/alac.m4a +b25bcc7ec3f5c19cdfc01a6bbd32edb8 *./tests/data/acodec/alac.m4a 389386 ./tests/data/acodec/alac.m4a 95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/alac.acodec.out.wav stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/pcm b/tests/ref/acodec/pcm index 033f8bc8c6..fc9dd8f29d 100644 --- a/tests/ref/acodec/pcm +++ b/tests/ref/acodec/pcm @@ -6,7 +6,7 @@ f443a8eeb1647ec1eeb8370c939e52d4 *./tests/data/acodec/pcm_mulaw.wav 529256 ./tests/data/acodec/pcm_mulaw.wav 1c3eeaa8814ebd4916780dff80ed6dc5 *./tests/data/pcm.acodec.out.wav stddev: 103.38 PSNR: 56.04 MAXDIFF: 644 bytes: 1058400/ 1058400 -b7936d7170e0efefb379349d81aed360 *./tests/data/acodec/pcm_s8.mov +760f85fb9f4e8aba326fb44ae84c9507 *./tests/data/acodec/pcm_s8.mov 530837 ./tests/data/acodec/pcm_s8.mov 652edf30f35ad89bf27bcc9d2f9c7b53 *./tests/data/pcm.acodec.out.wav stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400 @@ -14,7 +14,7 @@ stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400 529244 ./tests/data/acodec/pcm_u8.wav 652edf30f35ad89bf27bcc9d2f9c7b53 *./tests/data/pcm.acodec.out.wav stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400 -c42b9c04305455250366c84e17c1023f *./tests/data/acodec/pcm_s16be.mov +a4e18d1ca9ef5b8132a84d43625ddc47 *./tests/data/acodec/pcm_s16be.mov 1060037 ./tests/data/acodec/pcm_s16be.mov 95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400 @@ -30,7 +30,7 @@ c4f51bf32fad2f7af8ea5beedb56168b *./tests/data/acodec/pcm_s16le.mkv 1060638 ./tests/data/acodec/pcm_s16le.mkv 95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400 -07ffe7ffb78f3648b6524debdde5aec1 *./tests/data/acodec/pcm_s24be.mov +971d2d2633e41a0326fe2d04a2d0350f *./tests/data/acodec/pcm_s24be.mov 1589237 ./tests/data/acodec/pcm_s24be.mov 95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400 @@ -38,7 +38,7 @@ a85380fb79b0d4fff38e24ac1e34bb94 *./tests/data/acodec/pcm_s24le.wav 1587668 ./tests/data/acodec/pcm_s24le.wav 95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400 -d7792f0343cd66fda8b50b569e2bcc48 *./tests/data/acodec/pcm_s32be.mov +fc4f4e3e195bbde037ed31021d229f12 *./tests/data/acodec/pcm_s32be.mov 2118437 ./tests/data/acodec/pcm_s32be.mov 95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/wmav1 b/tests/ref/acodec/wmav1 index 916e4a8ab6..117aa12a8c 100644 --- a/tests/ref/acodec/wmav1 +++ b/tests/ref/acodec/wmav1 @@ -1,4 +1,4 @@ -26a7f6b0f0b7181df8df3fa589f6bf81 *./tests/data/acodec/wmav1.asf +0260385b8a54df11ad349f9ba8240fd8 *./tests/data/acodec/wmav1.asf 106004 ./tests/data/acodec/wmav1.asf -stddev:12245.52 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 -stddev: 2095.89 PSNR: 29.90 MAXDIFF:27658 bytes: 1056768/ 1058400 +stddev:12241.90 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 +stddev: 2074.79 PSNR: 29.99 MAXDIFF:27658 bytes: 1056768/ 1058400 diff --git a/tests/ref/acodec/wmav2 b/tests/ref/acodec/wmav2 index 622b6fcc36..43b19b7530 100644 --- a/tests/ref/acodec/wmav2 +++ b/tests/ref/acodec/wmav2 @@ -1,4 +1,4 @@ -7c6c0cb692af01b312ae345723674b5f *./tests/data/acodec/wmav2.asf +bdb4c312fb109f990be83a70f8ec9bdc *./tests/data/acodec/wmav2.asf 106044 ./tests/data/acodec/wmav2.asf -stddev:12249.93 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 -stddev: 2089.21 PSNR: 29.93 MAXDIFF:27650 bytes: 1056768/ 1058400 +stddev:12246.35 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 +stddev: 2068.08 PSNR: 30.02 MAXDIFF:27650 bytes: 1056768/ 1058400 diff --git a/tests/ref/fate/motionpixels b/tests/ref/fate/motionpixels index e588ed3e18..fa86f7379f 100644 --- a/tests/ref/fate/motionpixels +++ b/tests/ref/fate/motionpixels @@ -109,4 +109,3 @@ 0, 648003, 230400, 0xb343f372 0, 654003, 230400, 0xf7f1e588 0, 660003, 230400, 0x9682bdb2 -0, 666003, 230400, 0x538a3db8 diff --git a/tests/ref/fate/smacker b/tests/ref/fate/smacker index 85c4a9817c..df88a4ae8a 100644 --- a/tests/ref/fate/smacker +++ b/tests/ref/fate/smacker @@ -1,5 +1,5 @@ 0, 0, 192000, 0x8926d7fc -1, 0, 47240, 0xad778a78 +1, 0, 47240, 0x9974897c 0, 6390, 192000, 0x2506d384 0, 12780, 192000, 0x9a8dc93a 0, 19170, 192000, 0x4badb7f2 @@ -15,163 +15,163 @@ 0, 83070, 192000, 0x1a3d7971 0, 89460, 192000, 0xa1a65bd5 0, 95850, 192000, 0x344957b9 -1, 96408, 3128, 0x4c1564ae +1, 96408, 3128, 0x7e4064b4 0, 102240, 192000, 0xe23b5f4e -1, 102792, 3128, 0x34553309 +1, 102792, 3128, 0x80883301 0, 108630, 192000, 0xb5c2710b -1, 109176, 3136, 0xb474d246 +1, 109176, 3136, 0x2ad2d341 0, 115020, 192000, 0x7a25938f -1, 115576, 3128, 0x87b868ea +1, 115576, 3128, 0xda8468e3 0, 121410, 192000, 0x0a84e4c9 -1, 121959, 3136, 0xf1516dc3 +1, 121959, 3136, 0x9d6f6cdf 0, 127800, 192000, 0x94209b0d -1, 128359, 3128, 0x867563cb +1, 128359, 3128, 0x1aaa64b5 0, 134190, 192000, 0xf940e51f -1, 134743, 3128, 0x5200728c +1, 134743, 3128, 0x9182728b 0, 140580, 192000, 0xb9fdec42 -1, 141127, 3136, 0xeda118a0 +1, 141127, 3136, 0xfa8e17b3 0, 146970, 192000, 0x7b04a376 -1, 147527, 3128, 0x03e2c1d6 +1, 147527, 3128, 0x0dc3c1cf 0, 153360, 192000, 0x5fe0026b -1, 153910, 3136, 0xc3e862b6 +1, 153910, 3136, 0x0109639d 0, 159750, 192000, 0x775aca39 -1, 160310, 3128, 0x937a13be +1, 160310, 3128, 0x6d8a12d9 0, 166140, 192000, 0xae14fb32 -1, 166694, 3128, 0x7b1b9577 +1, 166694, 3128, 0x4b9a9597 0, 172530, 192000, 0x661106e5 -1, 173078, 3136, 0x042c7113 +1, 173078, 3136, 0x9112710e 0, 178920, 192000, 0xe8658dbf -1, 179478, 3128, 0xac48f451 +1, 179478, 3128, 0x8cccf522 0, 185310, 192000, 0x5359f0f9 -1, 185861, 3128, 0x018fbbe9 +1, 185861, 3128, 0x6594bbf3 0, 191700, 192000, 0xc1ec80f4 -1, 192245, 3136, 0xc62aa7ce +1, 192245, 3136, 0xd878a7d5 0, 198090, 192000, 0xca53806b -1, 198645, 3128, 0x106e3924 +1, 198645, 3128, 0xaa6e3905 0, 204480, 192000, 0xf0766b2e -1, 205029, 3136, 0xfeb82ecc +1, 205029, 3136, 0x2a062e04 0, 210870, 192000, 0x39962da8 -1, 211429, 3128, 0x7e7c005b +1, 211429, 3128, 0x84e4006a 0, 217260, 192000, 0x4171c37f -1, 217812, 3128, 0x949d3560 +1, 217812, 3128, 0x85183633 0, 223650, 192000, 0x3abf3b46 -1, 224196, 3136, 0x02bd4aff +1, 224196, 3136, 0xb62d4b02 0, 230040, 192000, 0xecc68313 -1, 230596, 3128, 0x4aaf4715 +1, 230596, 3128, 0xe209462a 0, 236430, 192000, 0xea339baf -1, 236980, 3136, 0x2958825f +1, 236980, 3136, 0x57c4824b 0, 242820, 192000, 0x616b8f16 -1, 243380, 3128, 0x99a5914d +1, 243380, 3128, 0x664a9163 0, 249210, 192000, 0xf77a8581 -1, 249763, 3128, 0xe67277a4 +1, 249763, 3128, 0xb4287874 0, 255600, 192000, 0xb315678b -1, 256147, 3136, 0x11296973 +1, 256147, 3136, 0xde626885 0, 261990, 192000, 0x0a4a5218 -1, 262547, 3128, 0x5cc362f7 +1, 262547, 3128, 0x919763c2 0, 268380, 192000, 0x98802be4 -1, 268931, 3128, 0x0c5e6586 +1, 268931, 3128, 0xa4f664e1 0, 274770, 192000, 0xa2f0fd94 -1, 275314, 3136, 0xe940b0f9 +1, 275314, 3136, 0xa0bab0d4 0, 281160, 192000, 0x6671c84f -1, 281714, 3128, 0x2c9292cc +1, 281714, 3128, 0xe938939c 0, 287550, 192000, 0x38327e31 -1, 288098, 3136, 0xa807c096 +1, 288098, 3136, 0x3679bfc7 0, 293940, 192000, 0xb85d3e08 -1, 294498, 3128, 0x9d2254d8 +1, 294498, 3128, 0xc96c55c3 0, 300330, 192000, 0xdc69eba9 -1, 300882, 3128, 0xe68015b0 +1, 300882, 3128, 0x119114d6 0, 306720, 192000, 0x8955a0b3 -1, 307265, 3136, 0x65d58029 +1, 307265, 3136, 0x42f3800f 0, 313110, 192000, 0x714a548b -1, 313665, 3128, 0xcffcc48c +1, 313665, 3128, 0x4250c4ad 0, 319500, 192000, 0xc0471de9 -1, 320049, 3136, 0x8c704944 +1, 320049, 3136, 0x5cdd4925 0, 325890, 192000, 0x2e16e039 -1, 326449, 3128, 0x1459231d +1, 326449, 3128, 0xa4c12360 0, 332280, 192000, 0x9fa4b033 -1, 332833, 3128, 0x7dde4839 +1, 332833, 3128, 0x849f48de 0, 338670, 192000, 0x4a0f9402 -1, 339216, 3136, 0xbb6890e2 +1, 339216, 3136, 0x6acd8ff9 0, 345060, 192000, 0x1f3e6843 -1, 345616, 3128, 0xcd9a8524 +1, 345616, 3128, 0xb2758556 0, 351450, 192000, 0x31774850 -1, 352000, 3128, 0xa244fc31 +1, 352000, 3128, 0x10f2fcb1 0, 357840, 192000, 0x9d5336a2 -1, 358384, 3136, 0x504e2bd9 +1, 358384, 3136, 0xf0f02b23 0, 364230, 192000, 0xf7de27a2 -1, 364784, 3128, 0x655858d8 +1, 364784, 3128, 0x64f759c6 0, 370620, 192000, 0x98c717ce -1, 371167, 3136, 0x46027610 +1, 371167, 3136, 0x7ec075e3 0, 377010, 192000, 0x615b10b8 -1, 377567, 3128, 0x4192d5e3 +1, 377567, 3128, 0xf981d51e 0, 383400, 192000, 0xd5bc0e7e -1, 383951, 3128, 0x21d2e7fe +1, 383951, 3128, 0xc622e8b9 0, 389790, 192000, 0xd5bc0e7e -1, 390335, 3136, 0x7c93e329 +1, 390335, 3136, 0xf632e2f8 0, 396180, 192000, 0xd5bc0e7e -1, 396735, 3128, 0xa67718c0 +1, 396735, 3128, 0xda561864 0, 402570, 192000, 0xd5bc0e7e -1, 403118, 3136, 0x9bb6e8a3 +1, 403118, 3136, 0x14d2e888 0, 408960, 192000, 0xd5bc0e7e -1, 409518, 3128, 0x0933b7a6 +1, 409518, 3128, 0x015bb869 0, 415350, 192000, 0xd5bc0e7e -1, 415902, 3128, 0x07f1fb57 +1, 415902, 3128, 0xedb1fb62 0, 421740, 192000, 0xd5bc0e7e -1, 422286, 3136, 0x8a050cfd +1, 422286, 3136, 0xe0560c41 0, 428130, 192000, 0xd5bc0e7e -1, 428686, 3128, 0xdb773c0b +1, 428686, 3128, 0x14773c9a 0, 434520, 192000, 0xd5bc0e7e -1, 435069, 3136, 0xd1281c53 +1, 435069, 3136, 0x850f1c82 0, 440910, 192000, 0xd5bc0e7e -1, 441469, 3128, 0x9f395324 +1, 441469, 3128, 0xb0bd5347 0, 447300, 192000, 0xd5bc0e7e -1, 447853, 3128, 0x5f13edec +1, 447853, 3128, 0x8f82edbf 0, 453690, 192000, 0xd5bc0e7e -1, 454237, 3136, 0x871cbecf +1, 454237, 3136, 0x493abee2 0, 460080, 192000, 0xd5bc0e7e -1, 460637, 3128, 0x799eff3e +1, 460637, 3128, 0xf5daff3f 0, 466470, 192000, 0xd5bc0e7e -1, 467020, 3128, 0x3f902762 +1, 467020, 3128, 0x78ad2690 0, 472860, 192000, 0xd5bc0e7e -1, 473404, 3136, 0x29f8bb04 +1, 473404, 3136, 0x490ebafc 0, 479250, 192000, 0xd5bc0e7e -1, 479804, 3128, 0xf3523ee9 +1, 479804, 3128, 0x70333fd2 0, 485640, 192000, 0xd5bc0e7e -1, 486188, 3136, 0x4405c435 +1, 486188, 3136, 0x8cb1c350 0, 492030, 192000, 0xd5bc0e7e -1, 492588, 3128, 0x892957cb +1, 492588, 3128, 0x8bd057cb 0, 498420, 192000, 0xd5bc0e7e -1, 498971, 3128, 0xdf483dbd +1, 498971, 3128, 0x161b3dbc 0, 504810, 192000, 0xd5bc0e7e -1, 505355, 3136, 0x5e8ab797 +1, 505355, 3136, 0xb47fb88a 0, 511200, 192000, 0xd5bc0e7e -1, 511755, 3128, 0x92e13820 +1, 511755, 3128, 0x474b381e 0, 517590, 192000, 0xd5bc0e7e -1, 518139, 3136, 0xfde719b6 +1, 518139, 3136, 0x07c519bb 0, 523980, 192000, 0xd5bc0e7e -1, 524539, 3128, 0x442f17ae +1, 524539, 3128, 0x15b916c8 0, 530370, 192000, 0xd5bc0e7e -1, 530922, 3128, 0x011af61f +1, 530922, 3128, 0x0ed7f6fb 0, 536760, 192000, 0xd5bc0e7e -1, 537306, 3136, 0x4e3e3a6d +1, 537306, 3136, 0x54d6397b 0, 543150, 192000, 0xd5bc0e7e -1, 543706, 3128, 0xc11242b9 +1, 543706, 3128, 0x437242bb 0, 549540, 192000, 0xd5bc0e7e -1, 550090, 3128, 0x01415b59 +1, 550090, 3128, 0x38f05c4d 0, 555930, 192000, 0xd5bc0e7e -1, 556473, 3136, 0x302e0e55 +1, 556473, 3136, 0x5d000e59 0, 562320, 192000, 0xd5bc0e7e -1, 562873, 3128, 0x20522d04 +1, 562873, 3128, 0xdeab2d04 0, 568710, 192000, 0xd5bc0e7e -1, 569257, 3136, 0x316a697d +1, 569257, 3136, 0x77de6880 0, 575100, 192000, 0xd5bc0e7e -1, 575657, 3128, 0x6d75ee27 +1, 575657, 3128, 0xbc87ef25 0, 581490, 192000, 0xd5bc0e7e -1, 582041, 3128, 0xcb008ae8 +1, 582041, 3128, 0xc1638ade 0, 587880, 192000, 0xd5bc0e7e -1, 588424, 3136, 0xd2664b51 +1, 588424, 3136, 0xcfb64a5f 0, 594270, 192000, 0xd5bc0e7e -1, 594824, 3128, 0xdfcab728 +1, 594824, 3128, 0x90b1b826 0, 600660, 192000, 0xd5bc0e7e 1, 601208, 3136, 0x00000000 0, 607050, 192000, 0xd5bc0e7e diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov index 940e518b5f..2071c5a743 100644 --- a/tests/ref/lavf/mov +++ b/tests/ref/lavf/mov @@ -1,3 +1,3 @@ -a901cd05609080e8f5c09ca5da7290f0 *./tests/data/lavf/lavf.mov +2e2529d01dbe42e4dd63580a351898f5 *./tests/data/lavf/lavf.mov 357681 ./tests/data/lavf/lavf.mov ./tests/data/lavf/lavf.mov CRC=0x2f6a9b26 diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index 58e75d17cd..869e40fd77 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,6 +1,3 @@ 785e38ddd2466046f30aa36399b8f8fa *./tests/data/lavf/lavf.mxf 525881 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x4ace0849 -b3174e2db508564c1cce0b5e3c1bc1bd *./tests/data/lavf/lavf.mxf_d10 -5330989 ./tests/data/lavf/lavf.mxf_d10 -./tests/data/lavf/lavf.mxf_d10 CRC=0xc3f4f92e diff --git a/tests/ref/lavf/mxf_d10 b/tests/ref/lavf/mxf_d10 new file mode 100644 index 0000000000..2582022d17 --- /dev/null +++ b/tests/ref/lavf/mxf_d10 @@ -0,0 +1,3 @@ +b3174e2db508564c1cce0b5e3c1bc1bd *./tests/data/lavf/lavf.mxf_d10 +5330989 ./tests/data/lavf/lavf.mxf_d10 +./tests/data/lavf/lavf.mxf_d10 CRC=0xc3f4f92e