diff --git a/.gitignore b/.gitignore index dd81f54e4e..1493f6c293 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 fa5d4fa90e..0000000000 --- a/Changelog +++ /dev/null @@ -1,710 +0,0 @@ -Entries are sorted chronologically from oldest to youngest within each release, -releases are sorted from youngest to oldest. - -version next: - -- openal input device added -- boxblur filter added -- BWF muxer -- Flash Screen Video 2 decoder - - -version 0.8: - - -- many many things we forgot because we rather write code than changelogs -- WebM support in Matroska de/muxer -- low overhead Ogg muxing -- MMS-TCP support -- VP8 de/encoding via libvpx -- Demuxer for On2's IVF format -- Pictor/PC Paint decoder -- HE-AAC v2 decoder -- libfaad2 wrapper removed -- DTS-ES extension (XCh) decoding support -- native VP8 decoder -- RTSP tunneling over HTTP -- RTP depacketization of SVQ3 -- -strict inofficial replaced by -strict unofficial -- ffplay -exitonkeydown and -exitonmousedown options added -- native GSM / GSM MS decoder -- RTP depacketization of QDM2 -- ANSI/ASCII art playback system -- Lego Mindstorms RSO de/muxer -- libavcore added (and subsequently removed) -- SubRip subtitle file muxer and demuxer -- Chinese AVS encoding via libxavs -- ffprobe -show_packets option added -- RTP packetization of Theora and Vorbis -- RTP depacketization of MP4A-LATM -- RTP packetization and depacketization of VP8 -- hflip filter -- Apple HTTP Live Streaming demuxer -- a64 codec -- MMS-HTTP support -- G.722 ADPCM audio encoder/decoder -- R10k video decoder -- ocv_smooth filter -- frei0r wrapper filter -- change crop filter syntax to width:height:x:y -- make the crop filter accept parametric expressions -- make ffprobe accept AVFormatContext options -- yadif filter -- blackframe filter -- Demuxer for Leitch/Harris' VR native stream format (LXF) -- RTP depacketization of the X-QT QuickTime format -- SAP (Session Announcement Protocol, RFC 2974) muxer and demuxer -- cropdetect filter -- ffmpeg -crop* options removed -- transpose filter added -- ffmpeg -force_key_frames option added -- demuxer for receiving raw rtp:// URLs without an SDP description -- single stream LATM/LOAS decoder -- setpts filter added -- Win64 support for optimized x86 assembly functions -- MJPEG/AVI1 to JPEG/JFIF bitstream filter -- ASS subtitle encoder and decoder -- IEC 61937 encapsulation for E-AC-3, TrueHD, DTS-HD (for HDMI passthrough) -- overlay filter added -- rename aspect filter to setdar, and pixelaspect to setsar -- IEC 61937 demuxer -- Mobotix .mxg demuxer -- frei0r source added -- hqdn3d filter added -- RTP depacketization of QCELP -- FLAC parser added -- gradfun filter added -- AMR-WB decoder -- replace the ocv_smooth filter with a more generic ocv filter -- Windows Televison (WTV) demuxer -- FFmpeg metadata format muxer and demuxer -- SubRip (srt) subtitle encoder and decoder -- floating-point AC-3 encoder added -- Lagarith decoder -- ffmpeg -copytb option added -- IVF muxer added -- Wing Commander IV movies decoder added -- movie source added -- Bink version 'b' audio and video decoder -- Bitmap Brothers JV playback system -- Apple HTTP Live Streaming protocol handler -- sndio support for playback and record -- Linux framebuffer input device added -- Chronomaster DFA decoder -- DPX image encoder -- MicroDVD subtitle file muxer and demuxer -- Playstation Portable PMP format demuxer -- fieldorder video filter added -- AAC encoding via libvo-aacenc -- AMR-WB encoding via libvo-amrwbenc -- xWMA demuxer -- Mobotix MxPEG decoder -- VP8 frame-multithreading -- NEON optimizations for VP8 -- Lots of deprecated API cruft removed -- fft and imdct optimizations for AVX (Sandy Bridge) processors -- showinfo filter added -- SMPTE 302M AES3 audio decoder -- Apple Core Audio Format muxer -- 9bit and 10bit per sample support in the H.264 decoder -- 9bit and 10bit FFV1 encoding / decoding -- split filter added -- select filter added -- sdl output device added -- libmpcodecs video filter support (3 times as many filters than before) -- mpeg2 aspect ratio dection fixed -- libxvid aspect pickiness fixed -- Frame multithreaded decoding -- E-AC-3 audio encoder -- ac3enc: add channel coupling support -- floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders. -- H264/MPEG frame-level multi-threading -- All av_metadata_* functions renamed to av_dict_* and moved to libavutil -- 4:4:4 H.264 decoding support -- 10-bit H.264 optimizations for x86 -- lut, lutrgb, and lutyuv filters added -- buffersink libavfilter sink added -- Bump libswscale for recently reported ABI break - - -version 0.7: - -- all the changes for 0.8, but keeping API/ABI compatibility with the 0.6 release - - -version 0.6: - -- PB-frame decoding for H.263 -- deprecated vhook subsystem removed -- deprecated old scaler removed -- VQF demuxer -- Alpha channel scaler -- PCX encoder -- RTP packetization of H.263 -- RTP packetization of AMR -- RTP depacketization of Vorbis -- CorePNG decoding support -- Cook multichannel decoding support -- introduced avlanguage helpers in libavformat -- 8088flex TMV demuxer and decoder -- per-stream language-tags extraction in asfdec -- V210 decoder and encoder -- remaining GPL parts in AC-3 decoder converted to LGPL -- QCP demuxer -- SoX native format muxer and demuxer -- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries -- DPX image decoder -- Electronic Arts Madcow decoder -- DivX (XSUB) subtitle encoder -- nonfree libamr support for AMR-NB/WB decoding/encoding removed -- experimental AAC encoder -- RTP depacketization of ASF and RTSP from WMS servers -- RTMP support in libavformat -- noX handling for OPT_BOOL X options -- Wave64 demuxer -- IEC-61937 compatible Muxer -- TwinVQ decoder -- Bluray (PGS) subtitle decoder -- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks) -- WMA Pro decoder -- Core Audio Format demuxer -- Atrac1 decoder -- MD STUDIO audio demuxer -- RF64 support in WAV demuxer -- MPEG-4 Audio Lossless Coding (ALS) decoder -- -formats option split into -formats, -codecs, -bsfs, and -protocols -- IV8 demuxer -- CDG demuxer and decoder -- R210 decoder -- Auravision Aura 1 and 2 decoders -- Deluxe Paint Animation playback system -- SIPR decoder -- Adobe Filmstrip muxer and demuxer -- RTP depacketization of H.263 -- Bink demuxer and audio/video decoders -- enable symbol versioning by default for linkers that support it -- IFF PBM/ILBM bitmap decoder -- concat protocol -- Indeo 5 decoder -- RTP depacketization of AMR -- WMA Voice decoder -- ffprobe tool -- AMR-NB decoder -- RTSP muxer -- HE-AAC v1 decoder -- Kega Game Video (KGV1) decoder -- VorbisComment writing for FLAC, Ogg FLAC and Ogg Speex files -- RTP depacketization of Theora -- HTTP Digest authentication -- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp -- Psygnosis YOP demuxer and video decoder -- spectral extension support in the E-AC-3 decoder -- unsharp video filter -- RTP hinting in the mov/3gp/mp4 muxer -- Dirac in Ogg demuxing -- seek to keyframes in Ogg -- 4:2:2 and 4:4:4 Theora decoding -- 35% faster VP3/Theora decoding -- faster AAC decoding -- faster H.264 decoding -- RealAudio 1.0 (14.4K) encoder - - -version 0.5: - -- DV50 AKA DVCPRO50 encoder, decoder, muxer and demuxer -- TechSmith Camtasia (TSCC) video decoder -- IBM Ultimotion (ULTI) video decoder -- Sierra Online audio file demuxer and decoder -- Apple QuickDraw (qdrw) video decoder -- Creative ADPCM audio decoder (16 bits as well as 8 bits schemes) -- Electronic Arts Multimedia (WVE/UV2/etc.) file demuxer -- Miro VideoXL (VIXL) video decoder -- H.261 video encoder -- QPEG video decoder -- Nullsoft Video (NSV) file demuxer -- Shorten audio decoder -- LOCO video decoder -- Apple Lossless Audio Codec (ALAC) decoder -- Winnov WNV1 video decoder -- Autodesk Animator Studio Codec (AASC) decoder -- Indeo 2 video decoder -- Fraps FPS1 video decoder -- Snow video encoder/decoder -- Sonic audio encoder/decoder -- Vorbis audio decoder -- Macromedia ADPCM decoder -- Duck TrueMotion 2 video decoder -- support for decoding FLX and DTA extensions in FLIC files -- H.264 custom quantization matrices support -- ffserver fixed, it should now be usable again -- QDM2 audio decoder -- Real Cooker audio decoder -- TrueSpeech audio decoder -- WMA2 audio decoder fixed, now all files should play correctly -- RealAudio 14.4 and 28.8 decoders fixed -- JPEG-LS decoder -- build system improvements -- tabs and trailing whitespace removed from the codebase -- CamStudio video decoder -- AIFF/AIFF-C audio format, encoding and decoding -- ADTS AAC file reading and writing -- Creative VOC file reading and writing -- American Laser Games multimedia (*.mm) playback system -- Zip Motion Blocks Video decoder -- improved Theora/VP3 decoder -- True Audio (TTA) decoder -- AVS demuxer and video decoder -- JPEG-LS encoder -- Smacker demuxer and decoder -- NuppelVideo/MythTV demuxer and RTjpeg decoder -- KMVC decoder -- MPEG-2 intra VLC support -- MPEG-2 4:2:2 encoder -- Flash Screen Video decoder -- GXF demuxer -- Chinese AVS decoder -- GXF muxer -- MXF demuxer -- VC-1/WMV3/WMV9 video decoder -- MacIntel support -- AVISynth support -- VMware video decoder -- VP5 video decoder -- VP6 video decoder -- WavPack lossless audio decoder -- Targa (.TGA) picture decoder -- Vorbis audio encoder -- Delphine Software .cin demuxer/audio and video decoder -- Tiertex .seq demuxer/video decoder -- MTV demuxer -- TIFF picture encoder and decoder -- GIF picture decoder -- Intel Music Coder decoder -- Zip Motion Blocks Video encoder -- Musepack decoder -- Flash Screen Video encoder -- Theora encoding via libtheora -- BMP encoder -- WMA encoder -- GSM-MS encoder and decoder -- DCA decoder -- DXA demuxer and decoder -- DNxHD decoder -- Gamecube movie (.THP) playback system -- Blackfin optimizations -- Interplay C93 demuxer and video decoder -- Bethsoft VID demuxer and video decoder -- CRYO APC demuxer -- Atrac3 decoder -- V.Flash PTX decoder -- RoQ muxer, RoQ audio encoder -- Renderware TXD demuxer and decoder -- extern C declarations for C++ removed from headers -- sws_flags command line option -- codebook generator -- RoQ video encoder -- QTRLE encoder -- OS/2 support removed and restored again -- AC-3 decoder -- NUT muxer -- additional SPARC (VIS) optimizations -- Matroska muxer -- slice-based parallel H.264 decoding -- Monkey's Audio demuxer and decoder -- AMV audio and video decoder -- DNxHD encoder -- H.264 PAFF decoding -- Nellymoser ASAO decoder -- Beam Software SIFF demuxer and decoder -- libvorbis Vorbis decoding removed in favor of native decoder -- IntraX8 (J-Frame) subdecoder for WMV2 and VC-1 -- Ogg (Theora, Vorbis and FLAC) muxer -- The "device" muxers and demuxers are now in a new libavdevice library -- PC Paintbrush PCX decoder -- Sun Rasterfile decoder -- TechnoTrend PVA demuxer -- Linux Media Labs MPEG-4 (LMLM4) demuxer -- AVM2 (Flash 9) SWF muxer -- QT variant of IMA ADPCM encoder -- VFW grabber -- iPod/iPhone compatible mp4 muxer -- Mimic decoder -- MSN TCP Webcam stream demuxer -- RL2 demuxer / decoder -- IFF demuxer -- 8SVX audio decoder -- non-recursive Makefiles -- BFI demuxer -- MAXIS EA XA (.xa) demuxer / decoder -- BFI video decoder -- OMA demuxer -- MLP/TrueHD decoder -- Electronic Arts CMV decoder -- Motion Pixels Video decoder -- Motion Pixels MVI demuxer -- removed animated GIF decoder/demuxer -- D-Cinema audio muxer -- Electronic Arts TGV decoder -- Apple Lossless Audio Codec (ALAC) encoder -- AAC decoder -- floating point PCM encoder/decoder -- MXF muxer -- DV100 AKA DVCPRO HD decoder and demuxer -- E-AC-3 support added to AC-3 decoder -- Nellymoser ASAO encoder -- ASS and SSA demuxer and muxer -- liba52 wrapper removed -- SVQ3 watermark decoding support -- Speex decoding via libspeex -- Electronic Arts TGQ decoder -- RV40 decoder -- QCELP / PureVoice decoder -- RV30 decoder -- hybrid WavPack support -- R3D REDCODE demuxer -- ALSA support for playback and record -- Electronic Arts TQI decoder -- OpenJPEG based JPEG 2000 decoder -- NC (NC4600) camera file demuxer -- Gopher client support -- MXF D-10 muxer -- generic metadata API -- flash ScreenVideo2 encoder - - -version 0.4.9-pre1: - -- DV encoder, DV muxer -- Microsoft RLE video decoder -- Microsoft Video-1 decoder -- Apple Animation (RLE) decoder -- Apple Graphics (SMC) decoder -- Apple Video (RPZA) decoder -- Cinepak decoder -- Sega FILM (CPK) file demuxer -- Westwood multimedia support (VQA & AUD files) -- Id Quake II CIN playback support -- 8BPS video decoder -- FLIC playback support -- RealVideo 2.0 (RV20) decoder -- Duck TrueMotion v1 (DUCK) video decoder -- Sierra VMD demuxer and video decoder -- MSZH and ZLIB decoder support -- SVQ1 video encoder -- AMR-WB support -- PPC optimizations -- rate distortion optimal cbp support -- rate distorted optimal ac prediction for MPEG-4 -- rate distorted optimal lambda->qp support -- AAC encoding with libfaac -- Sunplus JPEG codec (SP5X) support -- use Lagrange multipler instead of QP for ratecontrol -- Theora/VP3 decoding support -- XA and ADX ADPCM codecs -- export MPEG-2 active display area / pan scan -- Add support for configuring with IBM XLC -- floating point AAN DCT -- initial support for zygo video (not complete) -- RGB ffv1 support -- new audio/video parser API -- av_log() system -- av_read_frame() and av_seek_frame() support -- missing last frame fixes -- seek by mouse in ffplay -- noise reduction of DCT coefficients -- H.263 OBMC & 4MV support -- H.263 alternative inter vlc support -- H.263 loop filter -- H.263 slice structured mode -- interlaced DCT support for MPEG-2 encoding -- stuffing to stay above min_bitrate -- MB type & QP visualization -- frame stepping for ffplay -- interlaced motion estimation -- alternate scantable support -- SVCD scan offset support -- closed GOP support -- SSE2 FDCT -- quantizer noise shaping -- G.726 ADPCM audio codec -- MS ADPCM encoding -- multithreaded/SMP motion estimation -- multithreaded/SMP encoding for MPEG-1/MPEG-2/MPEG-4/H.263 -- multithreaded/SMP decoding for MPEG-2 -- FLAC decoder -- Metrowerks CodeWarrior suppport -- H.263+ custom pcf support -- nicer output for 'ffmpeg -formats' -- Matroska demuxer -- SGI image format, encoding and decoding -- H.264 loop filter support -- H.264 CABAC support -- nicer looking arrows for the motion vector visualization -- improved VCD support -- audio timestamp drift compensation -- MPEG-2 YUV 422/444 support -- polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample -- better image scaling -- H.261 support -- correctly interleave packets during encoding -- VIS optimized motion compensation -- intra_dc_precision>0 encoding support -- support reuse of motion vectors/MB types/field select values of the source video -- more accurate deblock filter -- padding support -- many optimizations and bugfixes -- FunCom ISS audio file demuxer and according ADPCM decoding - - -version 0.4.8: - -- MPEG-2 video encoding (Michael) -- Id RoQ playback subsystem (Mike Melanson and Tim Ferguson) -- Wing Commander III Movie (.mve) file playback subsystem (Mike Melanson - and Mario Brito) -- Xan DPCM audio decoder (Mario Brito) -- Interplay MVE playback subsystem (Mike Melanson) -- Duck DK3 and DK4 ADPCM audio decoders (Mike Melanson) - - -version 0.4.7: - -- RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, code from mplayerhq - (originally from public domain player for Amiga at http://www.honeypot.net/audio) -- current version now also compiles with older GCC (Fabrice) -- 4X multimedia playback system including 4xm file demuxer (Mike - Melanson), and 4X video and audio codecs (Michael) -- Creative YUV (CYUV) decoder (Mike Melanson) -- FFV1 codec (our very simple lossless intra only codec, compresses much better - than HuffYUV) (Michael) -- ASV1 (Asus), H.264, Intel indeo3 codecs have been added (various) -- tiny PNG encoder and decoder, tiny GIF decoder, PAM decoder (PPM with - alpha support), JPEG YUV colorspace support. (Fabrice Bellard) -- ffplay has been replaced with a newer version which uses SDL (optionally) - for multiplatform support (Fabrice) -- Sorenson Version 3 codec (SVQ3) support has been added (decoding only) - donated - by anonymous -- AMR format has been added (Johannes Carlsson) -- 3GP support has been added (Johannes Carlsson) -- VP3 codec has been added (Mike Melanson) -- more MPEG-1/2 fixes -- better multiplatform support, MS Visual Studio fixes (various) -- AltiVec optimizations (Magnus Damn and others) -- SH4 processor support has been added (BERO) -- new public interfaces (avcodec_get_pix_fmt) (Roman Shaposhnick) -- VOB streaming support (Brian Foley) -- better MP3 autodetection (Andriy Rysin) -- qpel encoding (Michael) -- 4mv+b frames encoding finally fixed (Michael) -- chroma ME (Michael) -- 5 comparison functions for ME (Michael) -- B-frame encoding speedup (Michael) -- WMV2 codec (unfinished - Michael) -- user specified diamond size for EPZS (Michael) -- Playstation STR playback subsystem, still experimental (Mike and Michael) -- ASV2 codec (Michael) -- CLJR decoder (Alex) - -.. And lots more new enhancements and fixes. - - -version 0.4.6: - -- completely new integer only MPEG audio layer 1/2/3 decoder rewritten - from scratch -- Recoded DCT and motion vector search with gcc (no longer depends on nasm) -- fix quantization bug in AC3 encoder -- added PCM codecs and format. Corrected WAV/AVI/ASF PCM issues -- added prototype ffplay program -- added GOB header parsing on H.263/H.263+ decoder (Juanjo) -- bug fix on MCBPC tables of H.263 (Juanjo) -- bug fix on DC coefficients of H.263 (Juanjo) -- added Advanced Prediction Mode on H.263/H.263+ decoder (Juanjo) -- now we can decode H.263 streams found in QuickTime files (Juanjo) -- now we can decode H.263 streams found in VIVO v1 files(Juanjo) -- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo) -- added GOB header for H.263/H.263+ coding on RTP mode (Juanjo) -- now H.263 picture size is returned on the first decoded frame (Juanjo) -- added first regression tests -- added MPEG-2 TS demuxer -- new demux API for libav -- more accurate and faster IDCT (Michael) -- faster and entropy-controlled motion search (Michael) -- two pass video encoding (Michael) -- new video rate control (Michael) -- added MSMPEG4V1, MSMPEGV2 and WMV1 support (Michael) -- great performance improvement of video encoders and decoders (Michael) -- new and faster bit readers and vlc parsers (Michael) -- high quality encoding mode: tries all macroblock/VLC types (Michael) -- added DV video decoder -- preliminary RTP/RTSP support in ffserver and libavformat -- H.263+ AIC decoding/encoding support (Juanjo) -- VCD MPEG-PS mode (Juanjo) -- PSNR stuff (Juanjo) -- simple stats output (Juanjo) -- 16-bit and 15-bit RGB/BGR/GBR support (Bisqwit) - - -version 0.4.5: - -- some header fixes (Zdenek Kabelac ) -- many MMX optimizations (Nick Kurshev ) -- added configure system (actually a small shell script) -- added MPEG audio layer 1/2/3 decoding using LGPL'ed mpglib by - Michael Hipp (temporary solution - waiting for integer only - decoder) -- fixed VIDIOCSYNC interrupt -- added Intel H.263 decoding support ('I263' AVI fourCC) -- added Real Video 1.0 decoding (needs further testing) -- simplified image formats again. Added PGM format (=grey - pgm). Renamed old PGM to PGMYUV. -- fixed msmpeg4 slice issues (tell me if you still find problems) -- fixed OpenDivX bugs with newer versions (added VOL header decoding) -- added support for MPlayer interface -- added macroblock skip optimization -- added MJPEG decoder -- added mmx/mmxext IDCT from libmpeg2 -- added pgmyuvpipe, ppm, and ppm_pipe formats (original patch by Celer - ) -- added pixel format conversion layer (e.g. for MJPEG or PPM) -- added deinterlacing option -- MPEG-1/2 fixes -- MPEG-4 vol header fixes (Jonathan Marsden ) -- ARM optimizations (Lionel Ulmer ). -- Windows porting of file converter -- added MJPEG raw format (input/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 155734bf81..f607b09a0e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 0.7.8 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. 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 e5ba8d2fac..cf03ddebe4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19,7 +19,7 @@ ffmpeg: ffmpeg.c Michael Niedermayer ffplay: - ffplay.c Michael Niedermayer + ffplay.c Marton Balint ffprobe: ffprobe.c Stefano Sabatini @@ -383,6 +383,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/VERSION b/VERSION new file mode 100644 index 0000000000..e7c7d3cc3c --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.7.8 diff --git a/configure b/configure index 3ad73df842..ed345daa1a 100755 --- a/configure +++ b/configure @@ -72,6 +72,9 @@ Standard options: --mandir=DIR install man page in DIR [PREFIX/share/man] Configuration options: + --enable-building enable building ONLY if you understand the + potential security risk posed by using this + branch (oldabi) --disable-static do not build static libraries [no] --enable-shared build shared libraries [no] --enable-gpl allow use of GPL code, the resulting libs @@ -162,6 +165,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 +181,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] @@ -909,6 +913,7 @@ CONFIG_LIST=" avfilter avformat avisynth + building bzlib crystalhd dct @@ -929,6 +934,8 @@ CONFIG_LIST=" h264pred hardcoded_tables huffman + libaacplus + libcdio libcelt libdc1394 libdirac @@ -1406,6 +1413,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" @@ -1422,6 +1430,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" @@ -1538,11 +1547,14 @@ 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 } +mxf_d10_test_deps="avfilter" +seek_lavf_mxf_d10_test_deps="mxf_d10_test" + test_deps _encoder _decoder \ adpcm_g726=g726 \ adpcm_ima_qt \ @@ -1928,6 +1940,22 @@ filter_cflags=echo filter_cppflags=echo filter_asflags=echo +if ! enabled building; then + cat <&1 | grep -q '^gcc.*LLVM'; then cc_type=llvm_gcc cc_version=__VERSION__ @@ -2190,7 +2218,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 @@ -2530,6 +2558,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 @@ -2580,6 +2609,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 @@ -2898,6 +2928,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" \ @@ -3063,6 +3094,10 @@ else fi check_cflags -fno-math-errno check_cflags -fno-signed-zeros +check_cc -mno-red-zone <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 535ca31446..7ea0c8d857 100644 --- a/doc/faq.texi +++ b/doc/faq.texi @@ -449,6 +449,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 832e3d8fe2..f3ca854dd3 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -712,8 +712,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 b41fce7ced..0fd6774e45 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1769,7 +1769,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 @@ -1787,11 +1787,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 diff --git a/doc/general.texi b/doc/general.texi index c5045b1095..7ca4d809e7 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -543,6 +543,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 @@ -1088,7 +1090,7 @@ These library packages are only available from @uref{http://sourceware.org/cygwinports/, Cygwin Ports}: @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 diff --git a/ffmpeg.c b/ffmpeg.c index 672ad2d152..e8d4d3c061 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" @@ -114,7 +114,9 @@ typedef struct ChapterMap { 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 double *ts_scale; static int nb_ts_scale; @@ -751,7 +753,7 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) st = ost->st; // FIXME: a more elegant solution is needed - memcpy(st, ic->streams[i], sizeof(AVStream)); + memcpy(st, &ic->streams[i], sizeof(AVStream)); st->info = av_malloc(sizeof(*st->info)); memcpy(st->info, ic->streams[i]->info, sizeof(*st->info)); avcodec_copy_context(st->codec, ic->streams[i]->codec); @@ -2072,7 +2074,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; @@ -2409,9 +2411,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); } } @@ -3944,7 +3946,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); } } @@ -3955,7 +3957,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); @@ -3972,7 +3974,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); } @@ -4378,7 +4380,11 @@ static void log_callback_null(void* ptr, int level, const char* fmt, va_list vl) static int opt_passlogfile(const char *opt, const char *arg) { pass_logfilename_prefix = 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 ed1bdf434d..58984b26fa 100644 --- a/ffplay.c +++ b/ffplay.c @@ -36,7 +36,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 @@ -1776,8 +1776,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); @@ -2133,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; diff --git a/ffprobe.c b/ffprobe.c index 8b66ae9628..555f52367e 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" diff --git a/ffserver.c b/ffserver.c index 1795a2a29c..538f5c0f29 100644 --- a/ffserver.c +++ b/ffserver.c @@ -40,7 +40,7 @@ #include "libavutil/mathematics.h" #include "libavutil/random_seed.h" #include "libavutil/parseutils.h" -#include "libavutil/opt.h" +#include "libavcodec/opt.h" #include #include #include @@ -95,7 +95,9 @@ static const char *http_state[] = { "RTSP_SEND_PACKET", }; +#if !FF_API_MAX_STREAMS #define MAX_STREAMS 20 +#endif #define IOBUFFER_INIT_SIZE 8192 @@ -2228,11 +2230,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) @@ -2240,9 +2242,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 */ @@ -2940,9 +2942,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; @@ -2955,8 +2959,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); @@ -3384,9 +3390,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 || @@ -3420,7 +3423,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); @@ -3663,7 +3666,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; @@ -3736,7 +3739,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) { @@ -3746,15 +3749,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); } diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index cf98e91766..e6638c7b4b 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 (bitstream_size > (1<<26) || length < bitstream_size + 12) + return -1; + 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 +717,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 +749,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 +763,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 +784,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 +829,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 +849,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 +885,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 8ae0185acb..92aca8163a 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/Makefile b/libavcodec/Makefile index c0b173767c..6347b95576 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 \ @@ -569,6 +570,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 @@ -589,6 +591,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/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 927d4314fa..bedb2438f2 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -1126,7 +1126,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); @@ -1166,7 +1166,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); @@ -2113,7 +2113,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) { @@ -2144,10 +2144,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: @@ -2156,6 +2158,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: @@ -2232,7 +2235,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/aacsbr.c b/libavcodec/aacsbr.c index 82092b385d..10b8daf280 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 @@ -1457,6 +1458,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/adpcm.c b/libavcodec/adpcm.c index 4e1299379f..9f2a09da3d 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -1335,10 +1335,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; } @@ -1353,6 +1354,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); diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 5480c7e78b..3309b14bbe 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/anm.c b/libavcodec/anm.c index b84aef1c1b..188f8296f3 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 300a0097d8..16749baa68 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,25 +207,18 @@ 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); } /** @@ -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/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/avcodec.h b/libavcodec/avcodec.h index 2a438ccc13..cd270e0be0 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -37,6 +37,12 @@ #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: @@ -115,6 +121,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, @@ -363,6 +372,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 @@ -776,10 +797,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 @@ -804,17 +821,6 @@ typedef struct AVPacket { * A combination of AV_PKT_FLAG values */ 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. @@ -844,6 +850,9 @@ typedef struct AVPacket { int64_t convergence_duration; } AVPacket; #define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted /** @@ -1258,6 +1267,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 @@ -1302,6 +1321,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 @@ -1359,6 +1381,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; @@ -1476,6 +1508,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. @@ -1754,6 +1789,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. @@ -1828,6 +1882,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. @@ -2546,6 +2616,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 @@ -2565,13 +2652,6 @@ typedef struct AVCodecContext { * @{ */ - /** - * 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. @@ -2634,7 +2714,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. */ @@ -3246,33 +3325,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; @@ -3280,6 +3332,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. * @@ -3443,6 +3503,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 @@ -3511,6 +3588,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 */ @@ -3561,6 +3646,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. * @@ -3722,6 +3814,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 @@ -3730,8 +3830,8 @@ 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 @@ -3803,6 +3903,25 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); */ 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. * Some decoders may support multiple frames in a single AVPacket, such @@ -3846,6 +3965,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 @@ -3890,6 +4028,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. @@ -4158,6 +4305,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. * @@ -4236,7 +4392,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. @@ -4250,7 +4406,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. @@ -4279,6 +4445,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 14f7cf0507..9e73695f5e 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; isyms[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 { @@ -344,14 +344,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; } @@ -375,7 +375,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; @@ -383,10 +383,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; } @@ -457,6 +459,7 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, { int i, j, len, len2, bsize, sign, v, v2; 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); @@ -464,10 +467,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++) { @@ -535,6 +542,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++) @@ -572,6 +581,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, int32_t 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; @@ -950,8 +975,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++) @@ -980,7 +1006,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 2d06aaa9e9..ac4da7f4e6 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -152,11 +152,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]; @@ -169,13 +176,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); @@ -190,15 +203,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; @@ -208,9 +226,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; @@ -246,6 +266,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) @@ -277,12 +299,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 b164ecdd11..191190d8e2 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -105,8 +105,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/cabac.c b/libavcodec/cabac.c index 5632bf811e..e03043f91f 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -150,10 +150,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; } } @@ -313,7 +317,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; } @@ -659,7 +665,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/cinepak.c b/libavcodec/cinepak.c index d2e0c26ddc..7ce4a1096d 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 2e7fd51f1f..8af149fa58 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 6def1ac2f7..7ed004e0bd 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1079,7 +1079,7 @@ 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); q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); @@ -1174,8 +1174,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/dca.c b/libavcodec/dca.c index e11439f939..78712b0f81 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -898,15 +898,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], 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/dsicinav.c b/libavcodec/dsicinav.c index 27f42041ba..0e8ae65210 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -217,7 +217,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; @@ -306,6 +310,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.h b/libavcodec/dsputil.h index f9894df80a..216c3b9557 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -115,6 +115,14 @@ void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); 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 1ee7aad5d1..ad213c88f1 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/dxva2_h264.c b/libavcodec/dxva2_h264.c index b5ffe02f44..3d5af31757 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -162,17 +162,19 @@ static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, D for (j = 0; j < 16; j++) qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j]; - for (i = 0; i < 2; i++) - for (j = 0; j < 64; j++) - qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][j]; + for (j = 0; j < 64; j++) { + qm->bScalingLists8x8[0][j] = h->pps.scaling_matrix8[0][j]; + qm->bScalingLists8x8[1][j] = h->pps.scaling_matrix8[3][j]; + } } else { for (i = 0; i < 6; i++) 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]]; + } } } diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 76de9c9810..20ec0a2265 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 74fb4c121b..b0c42f0222 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); @@ -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 991c5d12b8..26bf524339 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/error_resilience.c b/libavcodec/error_resilience.c index 3fb95ead88..90ed991153 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -660,7 +660,8 @@ 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].f.data[0]) + + if (h->list_count <= 0 || h->ref_count[0] <= 0 || !h->ref_list[0][0].f.data[0]) return 1; } diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 8d9dc72018..2b7a928ca0 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -1733,7 +1733,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 */ } @@ -1750,7 +1750,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/flacdec.c b/libavcodec/flacdec.c index d5662736b5..afc89203a3 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -226,9 +226,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; } diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 4df3a1b11b..6b19ba072d 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) { diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index be1ea50f75..fa925983a9 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -131,7 +131,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; @@ -171,7 +170,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 */ @@ -179,13 +182,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; @@ -193,8 +199,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 @@ -218,6 +222,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; @@ -234,13 +241,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: @@ -248,6 +248,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) { @@ -267,6 +269,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; @@ -283,6 +287,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; @@ -309,6 +315,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 */ @@ -318,6 +326,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; @@ -355,6 +365,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++]; @@ -369,6 +381,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; @@ -386,10 +400,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]) { @@ -402,7 +415,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: @@ -410,6 +422,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/golomb.h b/libavcodec/golomb.h index 90eeb30b54..8dff0322a7 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. diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index a526bc1c60..0ee5460fa7 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -599,6 +599,10 @@ retry: s->current_picture.f.pict_type = s->pict_type; s->current_picture.f.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/h263dec.c b/libavcodec/h263dec.c index 9df6fbaf6b..01474129e4 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -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; ilast_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 +689,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}; @@ -122,7 +119,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){ @@ -134,6 +131,23 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ return mode; } +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode) +{ + return check_intra_pred_mode(h, mode, 0); +} + +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode) +{ + return check_intra_pred_mode(h, mode, 1); +} + + const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){ int i, si, di; uint8_t *dst; @@ -174,20 +188,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; @@ -970,8 +992,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; @@ -983,17 +1009,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; } @@ -1005,6 +1034,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; @@ -1015,6 +1046,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; @@ -1022,10 +1055,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; @@ -1069,7 +1102,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){ @@ -1138,7 +1171,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++){ @@ -1376,7 +1412,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->f.reference == 0) @@ -2211,7 +2247,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]->f.reference = 0; h->delayed_pic[i]= NULL; @@ -2555,6 +2591,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ free_tables(h, 0); flush_dpb(s->avctx); MPV_common_end(s); + h->list_count = 0; } if (!s->context_initialized) { if (h != h0) { @@ -2616,7 +2653,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) { @@ -2812,6 +2852,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[1]= h->pps.ref_count[1]; if(h->slice_type_nos != AV_PICTURE_TYPE_I){ + unsigned max= (16<<(s->picture_structure != PICT_FRAME))-1; if(h->slice_type_nos == AV_PICTURE_TYPE_B){ h->direct_spatial_mv_pred= get_bits1(&s->gb); } @@ -2822,25 +2863,27 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ 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[0]-1 > max || h->ref_count[1]-1 > max){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); + h->ref_count[0]= h->ref_count[1]= 1; + return -1; } 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]; @@ -3593,7 +3636,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)); @@ -3616,15 +3659,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: @@ -3661,6 +3712,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) @@ -3698,6 +3752,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ if(hx->redundant_pic_count==0 && hx->intra_gb_ptr && hx->s.data_partitioning && 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) @@ -3837,7 +3894,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 d448fc3330..d1ea843b71 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 @@ -107,7 +109,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 { @@ -233,7 +235,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; @@ -585,7 +587,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 @@ -659,11 +661,16 @@ 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_intra16x16_pred_mode(H264Context *h, int mode); + +/** + * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode); 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); diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 6bbf87f0ba..ae18f8811b 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -2002,14 +2002,14 @@ decode_intra_mb: write_back_intra_pred_mode(h); if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1; } else { - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode ); + h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode( h, h->intra16x16_pred_mode ); 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_chroma_pred_mode( h, pred_mode ); 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 0cd147fd7a..ad039d5a96 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -735,12 +735,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_intra16x16_pred_mode(h, h->intra16x16_pred_mode); 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_chroma_pred_mode(h, get_ue_golomb_31(&s->gb)); 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 691dcf9d57..95e98d866a 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].f.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].f.mb_type[mb_xy + s->mb_stride]; b8_stride = 2+4*s->mb_stride; b4_stride *= 6; + if(IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])){ + mb_type_col[0] &= ~MB_TYPE_INTERLACED; + mb_type_col[1] &= ~MB_TYPE_INTERLACED; + } sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 27fba4b628..8fb82c4b5b 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -251,7 +251,7 @@ static int h264_parse(AVCodecParserContext *s, h->got_first = 1; if (avctx->extradata_size) { h->s.avctx = avctx; - ff_h264_decode_extradata(h); + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size); } } diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 61fb12ce0c..89e2502e0d 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -70,7 +70,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 +83,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 +143,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; @@ -333,6 +346,11 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->residual_color_transform_flag = get_bits1(&s->gb); sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; + if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) { + 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{ @@ -365,7 +383,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; } diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 6794bf3c9f..770e87976e 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]; 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 36f6d4e12f..f1372aab66 100644 --- a/libavcodec/h264pred_template.c +++ b/libavcodec/h264pred_template.c @@ -121,28 +121,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/idcinvideo.c b/libavcodec/idcinvideo.c index c47dc303bf..e441435e2c 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/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 9efed50955..0f7360851d 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -269,11 +269,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) { @@ -315,6 +344,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); @@ -487,6 +526,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 30d4758064..f7798e307d 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/interplayvideo.c b/libavcodec/interplayvideo.c index c8aa8bf65b..fdd4d8de11 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/j2k_dwt.c b/libavcodec/j2k_dwt.c index 9ba770ad83..ab7a1ab757 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 (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..96b4f64098 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -961,18 +961,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 +1007,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/jvdec.c b/libavcodec/jvdec.c index f4941992f6..f1fdee5d43 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -150,7 +150,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, FFMIN(video_size, (buf_end - buf) * 8)); for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 7ac4c01fba..aa0b55bd4a 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -233,7 +233,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 +264,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 +279,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; @@ -373,6 +374,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/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 92f1e98cdd..807f6ddfee 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -139,18 +139,25 @@ static int libgsm_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { 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/libvpxenc.c b/libavcodec/libvpxenc.c index 7e7a3012b8..15462ba507 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -481,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 670a7802e1..a6935fcf4e 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/mjpegdec.c b/libavcodec/mjpegdec.c index 4e38f46f7a..9172fb84da 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -318,8 +318,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,12 +329,15 @@ 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); @@ -881,14 +886,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)); + } } } } diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 9e59b92342..6f2e22120f 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/motion_est.c b/libavcodec/motion_est.c index 2517da5f9d..c8af093653 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -1016,7 +1016,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; @@ -1178,7 +1178,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/motionpixels.c b/libavcodec/motionpixels.c index a3868e10cc..ff1152822f 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -52,14 +52,16 @@ 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; 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; @@ -253,6 +255,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 +282,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 ba8828eb52..272e1b28ba 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 cae7244ed5..2f6bde3231 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); @@ -241,10 +243,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 +268,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 +410,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 91937c820c..c1e38f12c9 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -2473,10 +2473,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/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index db0db045e8..1e7fa1b558 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -834,8 +834,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..32dfd23bc1 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -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 441379d198..b3cc87de66 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -369,8 +369,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->allocated_edge_emu_buffer, (s->width+64)*2*21*2*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance + s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21*2; //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) @@ -1152,6 +1152,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 @@ -2161,6 +2164,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) @@ -2315,12 +2321,16 @@ 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->f.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->f.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->f.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->f.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->f.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->f.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 44a0dd671d..983a8556d6 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -124,7 +124,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 @@ -393,6 +393,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 a4d0167f36..bf6c4db580 100644 --- a/libavcodec/mpegvideo_common.h +++ b/libavcodec/mpegvideo_common.h @@ -725,7 +725,7 @@ 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 57b44c3199..7e3c4ca807 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -413,9 +413,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)) @@ -2008,7 +2009,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; diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c index 8f1f25966b..e864aab6c6 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 570c6282e0..8e490570fe 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 a153dc0603..23fecbfa26 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -156,6 +156,7 @@ static int decode_tag(AVCodecContext * avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; NellyMoserDecodeContext *s = avctx->priv_data; + int data_max = *data_size; int blocks, i; int16_t* samples; *data_size = 0; @@ -178,6 +179,8 @@ 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); diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 2a60fe47fc..3d73fd225b 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,18 +178,19 @@ 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; + int w, h, q, res; if (buf_size < 12) { av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); return -1; @@ -191,13 +198,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, w = AV_RL16(&buf[6]); h = AV_RL16(&buf[8]); q = buf[10]; - if (!codec_reinit(avctx, w, h, q)) - return -1; + 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[12]; buf_size -= 12; } - 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 +273,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 2380e74332..505377d7d9 100644 --- a/libavcodec/opt.h +++ b/libavcodec/opt.h @@ -1,18 +1,21 @@ /* - * This file is part of Libav. + * AVOptions + * copyright (c) 2005 Michael Niedermayer * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,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 d201072874..611651255c 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -445,6 +445,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"}, @@ -453,10 +454,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..ff0842fb5d 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, diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 70635671c2..59ff9851df 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -471,7 +471,8 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = PIX_FMT_MONOBLACK; } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = PIX_FMT_PAL8; - } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { avctx->pix_fmt = PIX_FMT_GRAY8A; } else { goto fail; 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 fb5c2f1e1e..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; diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c index 0b809784ab..4e5453e715 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,9 @@ 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 +86,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/qcelpdec.c b/libavcodec/qcelpdec.c index d565003a9e..9cd6cef209 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 7a1f3e1021..e2eb0eacb8 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -77,6 +77,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]; @@ -169,7 +170,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; @@ -1328,7 +1329,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; @@ -1354,6 +1355,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); @@ -1798,6 +1801,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; @@ -1820,6 +1825,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)); @@ -1888,6 +1896,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; @@ -1953,13 +1964,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); @@ -1969,7 +1987,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/qdrw.c b/libavcodec/qdrw.c index 4c9224c5e9..bbc0be029d 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 84e2b41629..595420bcb1 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -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 752bbc1323..f66bb2233a 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) { @@ -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 af8289e312..d085f04113 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 48e3282365..571783d3e0 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -186,13 +186,9 @@ static int raw_decode(AVCodecContext *avctx, (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 || avctx->pix_fmt==PIX_FMT_GRAY8 || 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/rv10.c b/libavcodec/rv10.c index dfd384a63b..ccf2098cfc 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -559,8 +559,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->f.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 */ diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index d2cc533d80..a228e158ad 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 ee9dd7db6b..5dcfd38f64 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1285,6 +1285,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; @@ -1416,25 +1427,35 @@ 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"); + if(get_slice_offset(avctx, slices_hdr, 0) < 0 || + get_slice_offset(avctx, slices_hdr, 0) > buf_size){ + av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); return -1; } - 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; } if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B) return -1; +#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) @@ -1460,13 +1486,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); @@ -1483,7 +1513,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/rv40.c b/libavcodec/rv40.c index 67676c26cc..cf416dc874 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/shorten.c b/libavcodec/shorten.c index b39fcbd0ef..1b69d0dadb 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -113,6 +113,7 @@ 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)){ @@ -124,9 +125,15 @@ static int allocate_buffers(ShortenContext *s) return -1; } - 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[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + if (!tmp_ptr) + return AVERROR(ENOMEM); + s->decoded[chan] = tmp_ptr; for (i=0; inwrap; i++) s->decoded[chan][i] = 0; s->decoded[chan] += s->nwrap; @@ -155,7 +162,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; } @@ -284,8 +291,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 @@ -467,6 +481,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; @@ -482,9 +502,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: { + int blocksize = get_uint(s, av_log2(s->blocksize)); + if (blocksize > s->blocksize) { + av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n"); + return AVERROR_PATCHWELCOME; + } + s->blocksize = blocksize; break; + } case FN_QUIT: *data_size = 0; return buf_size; diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index d6179a8edf..098d1074a7 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 bcfde4c8ba..c7eafbc261 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -134,11 +134,13 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx 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; @@ -290,7 +292,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 +301,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 +310,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 +319,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 +529,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 +560,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 +587,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 +607,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); @@ -619,9 +642,9 @@ 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++) + 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 +676,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 86f4282d54..24c5c14e49 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() \ @@ -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 734ff44735..53b7a8f12b 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -1606,8 +1606,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; @@ -1664,7 +1662,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); diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index 58bd2a2ab8..ea7a3e55c0 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -46,6 +46,7 @@ static av_cold int sunrast_init(AVCodecContext *avctx) { static int sunrast_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; 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; yavctx, "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) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 54c1231511..ec2ab6b97b 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) { @@ -571,7 +571,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; } @@ -614,7 +614,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_intra16x16_pred_mode(h, dir)) == -1){ av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); return -1; } @@ -643,7 +643,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; } @@ -653,7 +653,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; } @@ -713,7 +713,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) s->current_picture.f.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) { - h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8); + h->chroma_pred_mode = ff_h264_check_intra_chroma_pred_mode(h, DC_PRED8x8); } return 0; @@ -757,7 +757,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; } @@ -988,6 +988,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/targa.c b/libavcodec/targa.c index 884bae6cc9..6c01b695b2 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -177,6 +177,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 8f299be666..afe84b8a28 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 a42b27ffb1..f56b87b696 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -172,6 +172,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 { @@ -279,6 +281,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * 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); @@ -338,7 +342,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; @@ -452,6 +456,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; @@ -495,12 +501,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; @@ -520,9 +530,9 @@ static int decode_frame(AVCodecContext *avctx, } /* 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); @@ -546,23 +556,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 d635e17aad..1f1eafa76b 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -43,6 +43,7 @@ static const uint8_t type_sizes2[6] = { }; typedef struct TiffEncoderContext { + AVClass *avclass; AVCodecContext *avctx; AVFrame picture; @@ -217,6 +218,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; diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 3aa3444568..2837ceeb37 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 54c008714f..31b691dd0e 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 1ce1946333..0bd8c600bf 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -208,7 +208,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 e7aceebd5b..d49a4e5f3f 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 4299636f7b..1b9755cc19 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 49891ad04c..6f22fc1602 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -49,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; @@ -65,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) @@ -95,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; @@ -224,6 +231,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; @@ -592,6 +605,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD 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; @@ -749,6 +764,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) @@ -760,7 +791,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, @@ -799,6 +829,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) @@ -807,6 +851,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){ @@ -828,6 +877,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) @@ -1260,6 +1323,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 718e180942..01c42f5af1 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -282,7 +282,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 9504238b86..41cc1c8d21 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -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 228a02a255..e82546b69e 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -242,7 +242,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); @@ -294,7 +294,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); @@ -2329,7 +2329,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; @@ -3019,7 +3019,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; @@ -3095,7 +3095,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)); } @@ -3218,7 +3218,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)); } @@ -3226,9 +3226,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); @@ -3715,11 +3715,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) diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h index f3a547184d..e66d2dc76d 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 b19e8946d8..07b0f45592 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -20,9 +20,9 @@ #ifndef AVCODEC_VERSION_H #define AVCODEC_VERSION_H -#define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 9 -#define LIBAVCODEC_VERSION_MICRO 1 +#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, \ LIBAVCODEC_VERSION_MINOR, \ @@ -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 @@ -80,5 +113,8 @@ #ifndef FF_API_VERY_AGGRESSIVE #define FF_API_VERY_AGGRESSIVE (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 919789168e..6729af6af7 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 (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/vorbisdec.c b/libavcodec/vorbisdec.c index a29481d1b9..5d7a28e1db 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1611,7 +1611,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; @@ -1636,6 +1636,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; @@ -1651,8 +1658,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/vp3.c b/libavcodec/vp3.c index 7dcd14718b..8810516528 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; @@ -1777,10 +1798,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 +1822,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 +2011,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 +2037,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; } @@ -2341,6 +2357,23 @@ static void vp3_decode_flush(AVCodecContext *avctx) 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 = { .name = "theora", .type = AVMEDIA_TYPE_VIDEO, @@ -2352,6 +2385,7 @@ AVCodec ff_theora_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .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 @@ -2366,6 +2400,8 @@ AVCodec ff_vp3_decoder = { .decode = vp3_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .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 04df3e29a5..23d0acc631 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -118,7 +118,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; @@ -162,6 +162,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) @@ -184,7 +185,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])) { @@ -221,8 +223,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 0c6f45a767..dbbbd54c02 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -401,6 +401,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; @@ -465,6 +467,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; } @@ -513,6 +516,18 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (!res) return -1; + if (res == 2) { + 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; if (avctx->get_buffer(avctx, p) < 0) { @@ -539,7 +554,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; @@ -603,6 +619,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 b982435156..7d411f400c 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -48,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 e6132abeb6..84876b7146 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -139,8 +139,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) + if (buf_size < 0) { + if (s->framep[VP56_FRAME_CURRENT]->key_frame) + avcodec_set_dimensions(s->avctx, 0, 0); return 0; + } if (s->use_huffman) { s->parse_coeff = vp6_parse_coeff_huffman; init_get_bits(&s->gb, buf, buf_size<<3); @@ -215,8 +218,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; @@ -231,12 +234,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; @@ -281,15 +284,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 { @@ -299,6 +305,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) @@ -369,7 +376,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]--; @@ -406,6 +413,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]; } @@ -433,7 +442,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])) { @@ -474,8 +484,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 fb3f7f733a..4ddef084e4 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) @@ -273,7 +278,7 @@ static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size) 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 +492,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)\ @@ -919,7 +925,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 @@ -948,7 +955,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; } @@ -1749,6 +1756,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 67721097ef..8b57d79dbc 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)){ @@ -226,6 +230,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 +254,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 +276,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; diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index ba974bd089..d0cc8c0f76 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/wmadec.c b/libavcodec/wmadec.c index 9eaf230b01..11895a3996 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -109,6 +109,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; diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index d4ec0c02af..b87df0906b 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -309,10 +309,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; @@ -332,6 +328,18 @@ static av_cold int decode_init(AVCodecContext *avctx) 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 +351,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); @@ -1436,7 +1436,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"); diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 400d96386b..2e3a0f9ba6 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -401,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; @@ -422,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 + @@ -1077,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; @@ -1880,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/ws-snd1.c b/libavcodec/ws-snd1.c index 8e2e8ced99..61b83bd358 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; break; + case 1: smp = 2; 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/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/xan.c b/libavcodec/xan.c index 598d1e1423..21b5302000 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 @@ -505,6 +555,9 @@ static int xan_decode_frame(AVCodecContext *avctx, } buf_size = buf_end - buf; } + if (s->palettes_count <= 0) + 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 +572,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]) @@ -563,4 +617,3 @@ AVCodec ff_xan_wc3_decoder = { .capabilities = 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 e96e1ddbfe..938a5581c4 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)); @@ -302,6 +306,9 @@ static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) 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/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h index ab60e73c59..83af464865 100644 --- a/libavdevice/alsa-audio.h +++ b/libavdevice/alsa-audio.h @@ -43,7 +43,7 @@ typedef void (*ff_reorder_func)(const void *, void *, int); -#define ALSA_BUFFER_SIZE_MAX 32768 +#define ALSA_BUFFER_SIZE_MAX 65536 typedef struct { AVClass *class; diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index 7cb8f5497f..ce3167e8bf 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -22,8 +22,8 @@ #include "libavutil/avutil.h" #include "libavformat/avformat.h" -#define LIBAVDEVICE_VERSION_MAJOR 53 -#define LIBAVDEVICE_VERSION_MINOR 2 +#define LIBAVDEVICE_VERSION_MAJOR 52 +#define LIBAVDEVICE_VERSION_MINOR 6 #define LIBAVDEVICE_VERSION_MICRO 0 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 468c133f60..83474fe1c8 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 framerate_q; + AVRational framerate_q={0}; streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c index 7279817529..59a309a360 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){framerate_q.den, framerate_q.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 7003cdda5c..a57677c0e4 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -221,9 +221,6 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, if (link->out_chlayouts) avfilter_formats_changeref(&link->out_chlayouts, &filt->outputs[filt_dstpad_idx]->out_chlayouts); - if (link->out_packing) - avfilter_formats_changeref(&link->out_packing, - &filt->outputs[filt_dstpad_idx]->out_packing); return 0; } diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 1f26654559..434bc60289 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -28,9 +28,9 @@ #include "libavutil/pixfmt.h" #include "libavutil/rational.h" -#define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 27 -#define LIBAVFILTER_VERSION_MICRO 5 +#define LIBAVFILTER_VERSION_MAJOR 1 +#define LIBAVFILTER_VERSION_MINOR 81 +#define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ @@ -264,11 +264,6 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType type); */ AVFilterFormats *avfilter_all_channel_layouts(void); -/** - * Return a list of all audio packing formats. - */ -AVFilterFormats *avfilter_all_packing_formats(void); - /** * Return a format list which contains the intersection of the formats of * a and b. Also, all the references of a, all the references of b, and @@ -487,7 +482,6 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats); void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats); void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats); -void avfilter_set_common_packing_formats(AVFilterContext *ctx, AVFilterFormats *formats); /** Default handler for query_formats() */ int avfilter_default_query_formats(AVFilterContext *ctx); @@ -576,11 +570,6 @@ struct AVFilterContext { void *priv; ///< private data for use by the filter }; -enum AVFilterPacking { - AVFILTER_PACKED = 0, - AVFILTER_PLANAR, -}; - /** * A link between two filters. This contains pointers to the source and * destination filters between which this link exists, and the indexes of @@ -608,10 +597,9 @@ struct AVFilterLink { int w; ///< agreed upon image width int h; ///< agreed upon image height AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio - /* These parameters apply only to audio */ + /* These two parameters apply only to audio */ int64_t channel_layout; ///< channel layout of current buffer (see libavutil/audioconvert.h) int64_t sample_rate; ///< samples per second - int planar; ///< agreed upon packing mode of audio buffers. true if planar. int format; ///< agreed upon media format @@ -627,8 +615,6 @@ struct AVFilterLink { AVFilterFormats *in_chlayouts; AVFilterFormats *out_chlayouts; - AVFilterFormats *in_packing; - AVFilterFormats *out_packing; /** * The buffer reference currently being sent across the link by the source diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 8756e42bd4..04768617de 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -203,12 +203,8 @@ static void pick_format(AVFilterLink *link) link->channel_layout = link->in_chlayouts->formats[0]; avfilter_formats_unref(&link->in_chlayouts); avfilter_formats_unref(&link->out_chlayouts); - - link->in_packing->format_count = 1; - link->planar = link->in_packing->formats[0] == AVFILTER_PLANAR; - avfilter_formats_unref(&link->in_packing); - avfilter_formats_unref(&link->out_packing); } + } static void pick_formats(AVFilterGraph *graph) diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c index eef9fd1278..b03816dd24 100644 --- a/libavfilter/defaults.c +++ b/libavfilter/defaults.c @@ -239,19 +239,11 @@ void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats * offsetof(AVFilterLink, out_chlayouts)); } -void avfilter_set_common_packing_formats(AVFilterContext *ctx, AVFilterFormats *formats) -{ - set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO, - offsetof(AVFilterLink, in_packing), - offsetof(AVFilterLink, out_packing)); -} - int avfilter_default_query_formats(AVFilterContext *ctx) { avfilter_set_common_pixel_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_VIDEO)); avfilter_set_common_sample_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_AUDIO)); avfilter_set_common_channel_layouts(ctx, avfilter_all_channel_layouts()); - avfilter_set_common_packing_formats(ctx, avfilter_all_packing_formats()); return 0; } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 214718b779..b6e30e7ab4 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -173,17 +173,6 @@ AVFilterFormats *avfilter_all_channel_layouts(void) return avfilter_make_format64_list(chlayouts); } -AVFilterFormats *avfilter_all_packing_formats(void) -{ - static int packing[] = { - AVFILTER_PACKED, - AVFILTER_PLANAR, - -1, - }; - - return avfilter_make_format_list(packing); -} - void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) { *ref = f; 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_scale.c b/libavfilter/vf_scale.c index 044b2843bc..04b8d10663 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -237,9 +237,14 @@ 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 f4f72b9c64..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 }; 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/libavformat/4xm.c b/libavformat/4xm.c index 92a001f691..f535c49420 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -173,13 +173,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); 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]); diff --git a/libavformat/Makefile b/libavformat/Makefile index 9f5bfb42ad..a467f74fb7 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 5d4d2f64c5..aca42bbdc9 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/anm.c b/libavformat/anm.c index e35dc1517d..09e7dc7217 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 61590bdd35..cfac93381c 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -273,6 +273,8 @@ 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); } diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index d4026daae2..5cbbafd110 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -209,7 +209,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; } @@ -322,13 +322,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", @@ -348,7 +348,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); @@ -396,7 +396,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 14bd9514e7..7f8ec4c470 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -358,14 +358,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; @@ -807,6 +808,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){ @@ -841,10 +846,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) { @@ -969,17 +970,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); @@ -1134,8 +1124,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; } @@ -1155,7 +1151,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); @@ -1197,7 +1194,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, @@ -1269,7 +1268,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 59a4240bd3..dd93237a2b 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -145,6 +145,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. * @@ -257,6 +271,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. @@ -554,6 +572,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; @@ -569,6 +591,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; @@ -659,6 +689,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; @@ -677,9 +711,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. @@ -695,7 +736,11 @@ 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 */ #if FF_API_TIMESTAMP @@ -704,6 +749,16 @@ typedef struct AVFormatContext { */ attribute_deprecated int64_t timestamp; #endif +#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). */ @@ -743,9 +798,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; @@ -895,6 +958,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 @@ -919,6 +987,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 @@ -1135,6 +1215,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); /** @@ -1607,6 +1693,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 d454ce56f9..2579106da5 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -222,13 +222,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; @@ -608,18 +613,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); @@ -636,7 +638,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); } @@ -1090,14 +1092,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) { @@ -1361,11 +1363,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; } @@ -1416,7 +1420,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; avi->dts_max= INT_MIN; return 0; @@ -1430,6 +1435,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 20bbfc0375..8526b57f0b 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 8210cbd1da..8b7dd91c06 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 */ @@ -150,9 +152,9 @@ attribute_deprecated int url_poll(URLPollEntry *poll_table, int n, int timeout); * 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 */ /** * @} */ @@ -340,7 +342,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. @@ -350,6 +352,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); @@ -361,6 +366,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(). @@ -514,15 +535,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 + /** * @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 /** * @} */ @@ -539,7 +574,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 @@ -583,6 +622,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 e943aacb32..1c453f61f8 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; @@ -778,13 +780,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 +799,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;\ @@ -847,7 +852,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) if (!buffer) return AVERROR(ENOMEM); - *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h, + *s = avio_alloc_context(buffer, buffer_size, (h->flags & AVIO_WRONLY || h->flags & AVIO_RDWR), h, ffurl_read, ffurl_write, ffurl_seek); if (!*s) { av_free(buffer); @@ -877,15 +882,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 { @@ -915,7 +929,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) { @@ -1043,7 +1057,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); @@ -1084,7 +1098,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 e41e1c0277..32e6d1e7d2 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 89b2642c36..ad5ac05988 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/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/flvdec.c b/libavformat/flvdec.c index d3e3d77fce..e52d4b10f6 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -212,7 +212,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"); @@ -271,6 +271,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 d8d915e269..363309c75a 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -180,7 +180,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 898dce7eb5..d7d5e08b1b 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -426,7 +426,7 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { int pkt_len; struct gxf_stream_info *si = s->priv_data; - while (!pb->eof_reached) { + while (!url_feof(pb)) { AVStream *st; int track_type, track_id, ret; int field_nr, field_info, skip = 0; diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c index 8496384a5d..3d56eba287 100644 --- a/libavformat/gxfenc.c +++ b/libavformat/gxfenc.c @@ -342,8 +342,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; @@ -889,8 +890,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/idcin.c b/libavformat/idcin.c index 4a972c9aa8..826b17d5d5 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -86,6 +86,8 @@ typedef struct IdcinDemuxContext { int audio_present; int64_t pts; + + AVPaletteControl palctrl; } IdcinDemuxContext; static int idcin_probe(AVProbeData *p) @@ -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/img2.c b/libavformat/img2.c index 0531a1a8de..052d4d5ea3 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -145,11 +145,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) @@ -167,7 +167,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... */ @@ -321,7 +321,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); @@ -408,7 +408,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 72f15d3362..0bd9591ba7 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. diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index c5df1f6623..b1db03efe1 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 09ee23bdfd..1f75a4a956 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -208,6 +208,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 }, }; 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 01b6c3deb0..f93c76662f 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -95,7 +95,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 d4f41c224e..d5962b61d0 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -967,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; @@ -996,7 +997,12 @@ 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; if (pkt_data) { @@ -1020,7 +1026,12 @@ 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; if (pkt_data) { @@ -1444,7 +1455,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; @@ -1835,7 +1846,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; } } diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index ecc5e6bbb3..63edb815e1 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1211,7 +1211,6 @@ AVOutputFormat ff_matroska_muxer = { .write_packet = mkv_write_packet, .write_trailer = mkv_write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .subtitle_codec = CODEC_ID_SSA, }; #endif @@ -1245,6 +1244,5 @@ AVOutputFormat ff_matroska_audio_muxer = { .write_packet = mkv_write_packet, .write_trailer = mkv_write_trailer, .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 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 029baed211..49ff6bf0fc 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -232,7 +232,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); } @@ -260,7 +260,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 fdb29a01bf..d050752570 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -757,7 +757,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; @@ -766,6 +767,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; @@ -781,6 +786,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; @@ -1045,6 +1071,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 */ @@ -1054,7 +1081,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) @@ -1075,7 +1102,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 { @@ -1097,12 +1124,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; @@ -1740,7 +1767,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; } } @@ -2230,7 +2257,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 */ @@ -2239,12 +2266,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 }, @@ -2255,7 +2282,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 }, @@ -2377,14 +2404,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); @@ -2482,17 +2516,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 bf429c0f48..9ef56ac613 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -208,7 +208,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); @@ -1225,7 +1225,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); @@ -2060,7 +2061,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 73fce71cea..7fe7df2609 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -110,8 +110,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); } } @@ -174,7 +174,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 9caa65282b..2cb91f2845 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -55,11 +55,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 7a4cbbc8b7..9d84c10b97 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -264,7 +264,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 dc5d264b68..c58e07268a 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; } diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 5daffbb521..fc153386ca 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -710,6 +710,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); @@ -1093,7 +1098,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; @@ -1445,11 +1450,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) break; @@ -1883,10 +1892,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) { @@ -1896,6 +1903,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 5daacaf3f6..9cfe12178f 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -85,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 }, 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 c27fbfcd62..d0fe52176f 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -224,12 +224,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) @@ -239,7 +240,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; } @@ -291,12 +292,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; @@ -333,8 +338,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; diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index a9a992aae9..a6be493a62 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -32,7 +32,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 cd5592208a..eb43f6b8b1 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -29,7 +29,6 @@ DEALINGS IN THE SOFTWARE. **/ - #include #include "oggdec.h" #include "avformat.h" @@ -93,14 +92,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); diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index 89f2459e1f..ab35e86293 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -72,7 +72,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/options.c b/libavformat/options.c index fda325c7c7..4451b5e147 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -123,3 +123,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 4376e743c4..398e44e128 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 da47b8b14f..8b9b5e2483 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; @@ -243,7 +249,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 636d05c636..87be36e6ca 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -292,6 +292,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 effb7d3a00..732876f551 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); @@ -712,10 +740,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 +755,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 +826,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 +933,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/rtmpproto.c b/libavformat/rtmpproto.c index e3fce2e1fa..fba293eb2c 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -39,6 +39,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 */ @@ -160,7 +167,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); @@ -183,7 +190,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); @@ -206,7 +213,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); @@ -226,7 +233,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; @@ -248,7 +255,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; @@ -270,7 +277,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; @@ -304,7 +311,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; @@ -472,7 +479,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 @@ -483,16 +490,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) { @@ -500,7 +507,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; } } @@ -512,7 +519,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; } @@ -546,13 +553,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; } @@ -560,10 +567,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); @@ -572,12 +579,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: @@ -587,7 +594,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) { @@ -618,7 +625,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)); } @@ -645,7 +652,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, @@ -695,7 +702,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 f9252a9bb3..1244e9c508 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -83,6 +83,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, @@ -112,14 +117,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); @@ -130,14 +136,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..643ea7a5a0 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -233,8 +233,14 @@ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf, int cur_len = start_off + len_off - off; int prev_len = out_len; + void *newbuf; out_len += cur_len; - asf->buf = av_realloc(asf->buf, out_len); + if(FFMIN(cur_len, len - off)<0) + return -1; + newbuf = av_realloc(asf->buf, out_len); + if(!newbuf) + return -1; + asf->buf= newbuf; 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/rtsp.c b/libavformat/rtsp.c index 3b410a3043..a8dd41c7da 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1111,7 +1111,7 @@ 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; } } @@ -1256,7 +1256,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; } @@ -1383,7 +1383,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; } @@ -1404,7 +1404,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; } @@ -1447,7 +1447,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; } @@ -1794,7 +1794,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; } @@ -1850,7 +1850,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/sapdec.c b/libavformat/sapdec.c index 5351e9883d..ccc6a172e8 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 b84cce50a4..5fd17a56c6 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 7a84daf2ef..15234c70d6 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -113,11 +113,14 @@ static int film_read_header(AVFormatContext *s, film->audio_bits = scratch[22]; if (scratch[23] == 2) film->audio_type = CODEC_ID_ADPCM_ADX; - else 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 + 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; } @@ -176,6 +179,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); @@ -199,7 +204,7 @@ static int film_read_header(AVFormatContext *s, if (film->audio_type == CODEC_ID_ADPCM_ADX) audio_frame_counter += (film->sample_table[i].sample_size * 32 / (18 * film->audio_channels)); - else + 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 { @@ -252,6 +257,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 02e1e7b985..347ee4e709 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -286,11 +286,16 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) for(i = 0; i < 7; i++) { if(flags & 1) { int size; + uint8_t *tmpbuf; + size = avio_rl32(s->pb) - 4; 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 +304,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/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/tta.c b/libavformat/tta.c index 5b07b09b65..9104c78f7d 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 dda7ec2d13..8f7246de8c 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) @@ -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 || !s->local_port) && (h->flags & AVIO_FLAG_READ)) + if ((s->is_multicast || !s->local_port) && !(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 aa1220dbbc..6c9341764e 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -119,9 +119,15 @@ static void 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) { @@ -198,6 +204,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) { @@ -233,6 +247,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){ @@ -264,6 +299,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) { @@ -473,10 +540,15 @@ int av_open_input_stream(AVFormatContext **ic_ptr, if ((err = avformat_open_input(&ic, filename, fmt, &opts)) < 0) goto fail; + 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 *ic_ptr = ic; fail: + *ic_ptr = ic; av_dict_free(&opts); return err; } @@ -526,13 +598,19 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0; int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1; + void *buftmp; if (probe_size < offset) { 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) { @@ -608,7 +686,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; @@ -746,9 +824,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){ @@ -1001,7 +1076,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; } @@ -1139,7 +1214,8 @@ static int 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) && @@ -2405,9 +2481,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } { 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) @@ -2417,7 +2493,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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++; @@ -2672,28 +2748,38 @@ 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->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); } @@ -2710,6 +2796,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)) @@ -2718,6 +2811,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id) if (!streams) return NULL; s->streams = streams; +#endif st = av_mallocz(sizeof(AVStream)); if (!st) @@ -2795,6 +2889,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; @@ -2974,7 +3071,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; @@ -3020,6 +3119,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); @@ -3465,7 +3568,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; @@ -3538,6 +3641,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; @@ -3717,6 +3838,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 09e52da45f..993bbeb58c 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 6 +#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/westwood.c b/libavformat/westwood.c index 7712865e36..6b5fd51141 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/libavutil/Makefile b/libavutil/Makefile index 5ff5cb8e79..1025588657 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 efe3915350..52af66e722 100644 --- a/libavutil/arm/intmath.h +++ b/libavutil/arm/intmath.h @@ -106,7 +106,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 ffcac1c152..e73b5bae97 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 11 -#define LIBAVUTIL_VERSION_MICRO 1 +#define LIBAVUTIL_VERSION_MAJOR 50 +#define LIBAVUTIL_VERSION_MINOR 44 +#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,6 +104,13 @@ 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_NONE = 0, ///< Undefined AV_PICTURE_TYPE_I, ///< Intra 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/file.c b/libavutil/file.c index 31a3b7564f..6998c2946f 100644 --- a/libavutil/file.c +++ b/libavutil/file.c @@ -48,6 +48,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) { @@ -66,7 +67,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/imgutils.c b/libavutil/imgutils.c index 9447779c36..57031650c0 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -126,7 +126,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; @@ -275,3 +275,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 f976d210b9..b3582e5879 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -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/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 bac762ecc3..759a2433b8 100644 --- a/libavutil/lzo.c +++ b/libavutil/lzo.c @@ -175,11 +175,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/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 8fdf5b3a4d..467fbde08c 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/random_seed.c b/libavutil/random_seed.c index 81805e5db0..678cb8dfb4 100644 --- a/libavutil/random_seed.c +++ b/libavutil/random_seed.c @@ -23,6 +23,7 @@ #include #include #include "timer.h" +#include "avutil.h" #include "random_seed.h" static int read_random(uint32_t *dst, const char *file) @@ -80,3 +81,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 301d1606b4..a734d90498 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 97206200fb..9411479163 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 8bc0ddd9d8..78c9d991d7 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -249,7 +249,7 @@ static void hScale_altivec_real(SwsContext *c, 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)); @@ -288,7 +288,7 @@ static void hScale_altivec_real(SwsContext *c, 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)); @@ -374,7 +374,7 @@ static void hScale_altivec_real(SwsContext *c, 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/rgb2rgb.c b/libswscale/rgb2rgb.c index 9a7f698935..84ef43b774 100644 --- a/libswscale/rgb2rgb.c +++ b/libswscale/rgb2rgb.c @@ -123,6 +123,34 @@ void sws_rgb2rgb_init(void) rgb2rgb_init_x86(); } +#if LIBSWSCALE_VERSION_MAJOR < 1 +void palette8topacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) +{ + sws_convertPalette8ToPacked32(src, dst, num_pixels, palette); +} + +void palette8topacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) +{ + sws_convertPalette8ToPacked24(src, dst, num_pixels, palette); +} + +/** + * Palette is assumed to contain BGR16, see rgb32to16 to convert the palette. + */ +void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) +{ + long 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; @@ -818,8 +818,16 @@ int sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[], } } +#if LIBSWSCALE_VERSION_MAJOR < 1 +int sws_scale_ordered(SwsContext *c, const uint8_t* const src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + return sws_scale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride); +} +#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; @@ -828,7 +836,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 27b28049c0..afae13388c 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1432,6 +1432,13 @@ void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level) } } +#if LIBSWSCALE_VERSION_MAJOR < 1 +void sws_printVec(SwsVector *a) +{ + sws_printVec2(a, NULL, AV_LOG_DEBUG); +} +#endif + void sws_freeVec(SwsVector *a) { if (!a) return; diff --git a/tests/Makefile b/tests/Makefile index 34094da2b7..587fdd24fa 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -54,9 +54,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_VSYNTH1)): fate-vsynth1-vref $(filter-out %-vref,$(FATE_VSYNTH2)): fate-vsynth2-vref @@ -79,7 +82,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/tests/fate.mak b/tests/fate.mak index 0e3331178b..cf6c44e8e4 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 diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh index e1666c263c..5def09c2c9 100755 --- a/tests/lavfi-regression.sh +++ b/tests/lavfi-regression.sh @@ -50,9 +50,9 @@ do_lavfi_pixfmts(){ # exclude pixel formats which are not supported as input $ffmpeg -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^\..\.' | cut -d' ' -f2 | sort >$exclude_fmts - $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ fmt=substr($3, 5); print fmt }' | sort | comm -23 - $exclude_fmts >$out_fmts + $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ print $3 }' | sort | comm -23 - $exclude_fmts >$out_fmts - pix_fmts=$($showfiltfmts $filter $filter_args | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort | comm -12 - $out_fmts) + pix_fmts=$($showfiltfmts $filter $filter_args | awk -F '[ \r]' '/^INPUT/{ print $3 }' | sort | comm -12 - $out_fmts) for pix_fmt in $pix_fmts; do do_video_filter $pix_fmt "slicify=random,format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt done 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/fate/motionpixels b/tests/ref/fate/motionpixels index e588ed3e18..30651e92c6 100644 --- a/tests/ref/fate/motionpixels +++ b/tests/ref/fate/motionpixels @@ -109,4 +109,4 @@ 0, 648003, 230400, 0xb343f372 0, 654003, 230400, 0xf7f1e588 0, 660003, 230400, 0x9682bdb2 -0, 666003, 230400, 0x538a3db8 +0, 666003, 230400, 0x16f9aad8 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 73eb307081..869e40fd77 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,3 +1,3 @@ 785e38ddd2466046f30aa36399b8f8fa *./tests/data/lavf/lavf.mxf 525881 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0x4ace0849 \ No newline at end of file +./tests/data/lavf/lavf.mxf CRC=0x4ace0849 diff --git a/tools/lavfi-showfiltfmts.c b/tools/lavfi-showfiltfmts.c index a4541bac82..cc19e00a8c 100644 --- a/tools/lavfi-showfiltfmts.c +++ b/tools/lavfi-showfiltfmts.c @@ -20,61 +20,15 @@ #include "libavformat/avformat.h" #include "libavutil/pixdesc.h" -#include "libavutil/samplefmt.h" #include "libavfilter/avfilter.h" -static void print_formats(AVFilterContext *filter_ctx) -{ - int i, j; - -#define PRINT_FMTS(inout, outin, INOUT) \ - for (i = 0; i < filter_ctx->input_count; i++) { \ - if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_VIDEO) { \ - AVFilterFormats *fmts = \ - filter_ctx->inout##puts[i]->outin##_formats; \ - for (j = 0; j < fmts->format_count; j++) \ - printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ - av_get_pix_fmt_name(fmts->formats[j])); \ - } else if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_AUDIO) { \ - AVFilterFormats *fmts; \ - \ - fmts = filter_ctx->inout##puts[i]->outin##_formats; \ - for (j = 0; j < fmts->format_count; j++) \ - printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ - av_get_sample_fmt_name(fmts->formats[j])); \ - \ - fmts = filter_ctx->inout##puts[i]->outin##_chlayouts; \ - for (j = 0; j < fmts->format_count; j++) { \ - char buf[256]; \ - av_get_channel_layout_string(buf, sizeof(buf), -1, \ - fmts->formats[j]); \ - printf(#INOUT "PUT[%d] %s: chlayout:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, buf); \ - } \ - \ - fmts = filter_ctx->inout##puts[i]->outin##_packing; \ - for (j = 0; j < fmts->format_count; j++) { \ - printf(#INOUT "PUT[%d] %s: packing:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ - fmts->formats[j] == AVFILTER_PACKED ? \ - "packed" : "planar"); \ - } \ - } \ - } \ - - PRINT_FMTS(in, out, IN); - PRINT_FMTS(out, in, OUT); -} - int main(int argc, char **argv) { AVFilter *filter; AVFilterContext *filter_ctx; const char *filter_name; const char *filter_args = NULL; - int i; + int i, j; av_log_set_level(AV_LOG_DEBUG); @@ -121,7 +75,23 @@ int main(int argc, char **argv) else avfilter_default_query_formats(filter_ctx); - print_formats(filter_ctx); + /* print the supported formats in input */ + for (i = 0; i < filter_ctx->input_count; i++) { + AVFilterFormats *fmts = filter_ctx->inputs[i]->out_formats; + for (j = 0; j < fmts->format_count; j++) + printf("INPUT[%d] %s: %s\n", + i, filter_ctx->filter->inputs[i].name, + av_get_pix_fmt_name(fmts->formats[j])); + } + + /* print the supported formats in output */ + for (i = 0; i < filter_ctx->output_count; i++) { + AVFilterFormats *fmts = filter_ctx->outputs[i]->in_formats; + for (j = 0; j < fmts->format_count; j++) + printf("OUTPUT[%d] %s: %s\n", + i, filter_ctx->filter->outputs[i].name, + av_get_pix_fmt_name(fmts->formats[j])); + } avfilter_free(filter_ctx); fflush(stdout);