diff --git a/.gitignore b/.gitignore index 5397a35380..01d93b9f1f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ *.d *.def *.dll -*.dylib *.exe *.exp *.gcda @@ -18,33 +17,20 @@ *.ver *-example *-test -*_g /.config /.version -/ffmpeg -/ffplay -/ffprobe -/ffserver +/avconv +/avplay +/avprobe +/avserver /config.* /coverage.info +/version.h /doc/*.1 -/doc/*.3 /doc/*.html /doc/*.pod -/doc/config.texi /doc/avoptions_codec.texi /doc/avoptions_format.texi -/doc/examples/decoding_encoding -/doc/examples/demuxing_decoding -/doc/examples/filtering_audio -/doc/examples/filtering_video -/doc/examples/metadata -/doc/examples/muxing -/doc/examples/pc-uninstalled -/doc/examples/resampling_audio -/doc/examples/scaling_video -/doc/examples/transcode_aac -/doc/fate.txt /doc/doxy/html/ /doc/examples/output /doc/examples/transcode_aac @@ -54,29 +40,18 @@ /libavcodec/*_tables.c /libavcodec/*_tables.h /libavutil/avconfig.h -/libavutil/ffversion.h /tests/audiogen /tests/base64 /tests/data/ /tests/rotozoom /tests/tiny_psnr -/tests/tiny_ssim /tests/videogen /tests/vsynth1/ /tools/aviocat -/tools/ffbisect -/tools/bisect.need -/tools/crypto_bench /tools/cws2fws -/tools/fourcc2pixfmt -/tools/ffescape -/tools/ffeval -/tools/ffhash /tools/graph2dot /tools/ismindex /tools/pktdumper /tools/probetest /tools/qt-faststart /tools/trasher -/tools/seek_print -/tools/zmqsend diff --git a/CREDITS b/CREDITS index e29f0b853c..4a537786f0 100644 --- a/CREDITS +++ b/CREDITS @@ -1,6 +1,55 @@ -See the Git history of the project (git://source.ffmpeg.org/ffmpeg) to -get the names of people who have contributed to FFmpeg. +This file contains the names of some of the people who have contributed to +Libav/FFmpeg. The names are sorted alphabetically by last name. As this file is +currently quite outdated and git serves as a much better tool for determining +authorship, it remains here for historical reasons only. -To check the log, you can type the command "git log" in the FFmpeg -source directory, or browse the online repository at -http://source.ffmpeg.org. +Dénes Balatoni +Michel Bardiaux +Fabrice Bellard +Patrice Bensoussan +Alex Beregszaszi +BERO +Thilo Borgmann +Mario Brito +Ronald Bultje +Alex Converse +Maarten Daniels +Reimar Doeffinger +Tim Ferguson +Brian Foley +Arpad Gereoffy +Philip Gladstone +Vladimir Gneushev +Roine Gustafsson +David Hammerton +Wolfgang Hesseler +Marc Hoffman +Falk Hueffner +Aurélien Jacobs +Steven Johnson +Zdenek Kabelac +Robin Kay +Todd Kirby +Nick Kurshev +Benjamin Larsson +Loïc Le Loarer +Daniel Maas +Mike Melanson +Loren Merritt +Jeff Muizelaar +Michael Niedermayer +François Revol +Peter Ross +Måns Rullgård +Stefano Sabatini +Roman Shaposhnik +Oded Shimon +Dieter Shirley +Konstantin Shishkov +Juan J. Sierralta +Ewald Snel +Sascha Sommer +Leon van Stuivenberg +Roberto Togni +Lionel Ulmer +Reynaldo Verdejo diff --git a/Changelog b/Changelog index 2cab110f85..efd474a5d8 100644 --- a/Changelog +++ b/Changelog @@ -1,239 +1,109 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version - -- HNM version 4 demuxer and video decoder -- Live HDS muxer -- setsar/setdar filters now support variables in ratio expressions -- elbg filter -- string validation in ffprobe -- support for decoding through VDPAU in ffmpeg (the -hwaccel option) -- complete Voxware MetaSound decoder -- remove mp3_header_compress bitstream filter -- Windows resource files for shared libraries -- aeval filter -- stereoscopic 3d metadata handling -- WebP encoding via libwebp -- ATRAC3+ decoder -- VP8 in Ogg demuxing -- side & metadata support in NUT - - -version 2.1: - -- aecho filter -- perspective filter ported from libmpcodecs -- ffprobe -show_programs option -- compand filter +version 10: +- av_strnstr +- support ID3v2 tags in ASF files +- reference-counting for AVFrame and AVPacket data +- avconv now fails when input options are used for output file + or vice versa +- avconv options -filter_script and -filter_complex_script, which allow a + filtergraph description to be read from a file +- uniform options syntax across all filters +- interlace filter +- JPEG 2000 decoder +- asetpts filter (same as setpts, but for audio) +- trim and atrim filters +- avconv -t and -ss (output-only) options are now sample-accurate when + transcoding audio +- Matroska muxer can now put the index at the beginning of the file. +- avconv -deinterlace option removed, the yadif filter should be used instead +- Apple Intermediate Codec decoder +- Escape 130 video decoder +- support for slice multithreading in libavfilter +- VC-1 interlaced B-frame support +- support for WavPack muxing (raw and in Matroska) +- Go2Webinar decoder +- WavPack encoding through libwavpack +- Added the -n parameter to avconv - RTMP seek support -- when transcoding with ffmpeg (i.e. not streamcopying), -ss is now accurate +- when transcoding with avconv (i.e. not streamcopying), -ss is now accurate even when used as an input option. Previous behavior can be restored with the -noaccurate_seek option. -- ffmpeg -t option can now be used for inputs, to limit the duration of +- avconv -t option can now be used for inputs, to limit the duration of data read from an input file -- incomplete Voxware MetaSound decoder -- read EXIF metadata from JPEG -- DVB teletext decoder -- phase filter ported from libmpcodecs -- w3fdif filter -- Opus support in Matroska -- FFV1 version 1.3 is stable and no longer experimental -- FFV1: YUVA(444,422,420) 9, 10 and 16 bit support -- changed DTS stream id in lavf mpeg ps muxer from 0x8a to 0x88, to be - more consistent with other muxers. -- adelay filter -- pullup filter ported from libmpcodecs -- ffprobe -read_intervals option -- Lossless and alpha support for WebP decoder +- Voxware MetaSound decoder +- WebP decoder - Error Resilient AAC syntax (ER AAC LC) decoding - Low Delay AAC (ER AAC LD) decoding - mux chapters in ASF files -- SFTP protocol (via libssh) -- libx264: add ability to encode in YUVJ422P and YUVJ444P -- Fraps: use BT.709 colorspace by default for yuv, as reference fraps decoder does -- make decoding alpha optional for prores, ffv1 and vp6 by setting - the skip_alpha flag. -- ladspa wrapper filter -- native VP9 decoder -- dpx parser -- max_error_rate parameter in ffmpeg -- PulseAudio output device -- ReplayGain scanner +- Opus in Ogg demuxing - Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support) -- Linux framebuffer output device +- F4V muxer +- HNM version 4 demuxer and video decoder - HEVC decoder - raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing -- mergeplanes filter +- remove avplay -vismv option, which has not worked for a long time +- Live HDS muxer +- setsar/setdar filters now support variables in ratio expressions +- dar variable in the scale filter now returns the actual DAR (i.e. a * sar) +- VP9 decoder +- support for decoding through VDPAU in avconv (the -hwaccel option) +- remove mp3_header_(de)compress bitstream filters +- stereoscopic 3d metadata handling +- png standalone parser +- WebP encoding via libwebp -version 2.0: - -- curves filter -- reference-counting for AVFrame and AVPacket data -- ffmpeg now fails when input options are used for output file - or vice versa -- support for Monkey's Audio versions from 3.93 -- perms and aperms filters -- audio filtering support in ffplay -- 10% faster aac encoding on x86 and MIPS -- sine audio filter source -- WebP demuxing and decoding support -- ffmpeg options -filter_script and -filter_complex_script, which allow a - filtergraph description to be read from a file -- OpenCL support -- audio phaser filter -- separatefields filter -- libquvi demuxer -- uniform options syntax across all filters -- telecine filter -- interlace filter -- smptehdbars source -- inverse telecine filters (fieldmatch and decimate) -- colorbalance filter -- colorchannelmixer filter -- The matroska demuxer can now output proper verbatim ASS packets. It will - become the default at the next libavformat major bump. -- decent native animated GIF encoding -- asetrate filter -- interleave filter -- timeline editing with filters -- vidstabdetect and vidstabtransform filters for video stabilization using - the vid.stab library -- astats filter -- trim and atrim filters -- ffmpeg -t and -ss (output-only) options are now sample-accurate when - transcoding audio -- Matroska muxer can now put the index at the beginning of the file. -- extractplanes filter -- avectorscope filter -- ADPCM DTK decoder -- ADP demuxer -- RSD demuxer -- RedSpark demuxer -- ADPCM IMA Radical decoder -- zmq filters -- DCT denoiser filter (dctdnoiz) -- Wavelet denoiser filter ported from libmpcodecs as owdenoise (formerly "ow") -- Apple Intermediate Codec decoder -- Escape 130 video decoder -- FTP protocol support -- V4L2 output device -- 3D LUT filter (lut3d) -- SMPTE 302M audio encoder -- support for slice multithreading in libavfilter -- Hald CLUT support (generation and filtering) -- VC-1 interlaced B-frame support -- support for WavPack muxing (raw and in Matroska) -- XVideo output device -- vignette filter -- True Audio (TTA) encoder -- Go2Webinar decoder -- mcdeint filter ported from libmpcodecs -- sab filter ported from libmpcodecs -- ffprobe -show_chapters option -- WavPack encoding through libwavpack -- rotate filter -- spp filter ported from libmpcodecs -- libgme support -- psnr filter - - -version 1.2: - +version 9: +- av_basename and av_dirname +- adobe and limelight publisher authentication in RTMP - VDPAU hardware acceleration through normal hwaccel - SRTP support -- Error diffusion dither in Swscale -- Chained Ogg support -- Theora Midstream reconfiguration support -- EVRC decoder -- audio fade filter -- filtering audio with unknown channel layout -- allpass, bass, bandpass, bandreject, biquad, equalizer, highpass, lowpass - and treble audio filter -- improved showspectrum filter, with multichannel support and sox-like colors -- histogram filter -- tee muxer -- il filter ported from libmpcodecs -- support ID3v2 tags in ASF files -- encrypted TTA stream decoding support -- RF64 support in WAV muxer -- noise filter ported from libmpcodecs -- Subtitles character encoding conversion -- blend filter -- stereo3d filter ported from libmpcodecs -version 1.1: - -- stream disposition information printing in ffprobe -- filter for loudness analysis following EBU R128 -- Opus encoder using libopus -- ffprobe -select_streams option -- Pinnacle TARGA CineWave YUV16 decoder -- TAK demuxer, decoder and parser -- DTS-HD demuxer -- remove -same_quant, it hasn't worked for years -- FFM2 support -- X-Face image encoder and decoder +version 9_beta3: +- ashowinfo audio filter - 24-bit FLAC encoding +- audio volume filter +- deprecated the avconv -vol option. the volume filter is to be used instead. - multi-channel ALAC encoding up to 7.1 +- TAK demuxer, parser, and decoder +- adaptive frame-level multithreading for H.264 + + +version 9_beta2: - metadata (INFO tag) support in WAV muxer -- subtitles raw text decoder - support for building DLLs using MSVC -- LVF demuxer -- ffescape tool -- metadata (info chunk) support in CAF muxer -- field filter ported from libmpcodecs -- AVR demuxer -- geq filter ported from libmpcodecs -- remove ffserver daemon mode -- AST muxer/demuxer -- new expansion syntax for drawtext -- BRender PIX image decoder -- ffprobe -show_entries option -- ffprobe -sections option -- ADPCM IMA Dialogic decoder -- BRSTM demuxer -- animated GIF decoder and demuxer -- PVF demuxer -- subtitles filter -- IRCAM muxer/demuxer -- Paris Audio File demuxer -- Virtual concatenation demuxer -- VobSub demuxer -- JSON captions for TED talks decoding support -- SOX Resampler support in libswresample -- aselect filter -- SGI RLE 8-bit decoder -- Silicon Graphics Motion Video Compressor 1 & 2 decoder -- Silicon Graphics Movie demuxer -- apad filter -- Resolution & pixel format change support with multithreading for H.264 -- documentation split into per-component manuals -- pp (postproc) filter ported from MPlayer -- NIST Sphere demuxer -- MPL2, VPlayer, MPlayer, AQTitle, PJS and SubViewer v1 subtitles demuxers and decoders -- Sony Wave64 muxer -- adobe and limelight publisher authentication in RTMP -- data: URI scheme +- remove avserver daemon mode - support building on the Plan 9 operating system -- kerndeint filter ported from MPlayer -- histeq filter ported from VirtualDub -- Megalux Frame demuxer -- 012v decoder -- Improved AVC Intra decoding support +- ffv1: support version 1.3 -version 1.0: +version 9_beta1: -- INI and flat output in ffprobe -- Scene detection in libavfilter +- XWD encoder and decoder +- Support for fragmentation in the mov/mp4 muxer +- ISMV (Smooth Streaming) muxer +- CDXL demuxer and decoder +- Apple ProRes encoder +- Sun Rasterfile Encoder +- remove libpostproc +- ID3v2 attached pictures reading and writing +- WMA Lossless decoder +- XBM encoder +- RealAudio Lossless decoder +- ZeroCodec decoder +- drop support for avconv without libavfilter +- add libavresample audio conversion library +- audio filters support in libavfilter and avconv +- add fps filter +- audio split filter +- audio mix filter +- avprobe output is now standard INI or JSON. The old format can still + be used with -of old. - Indeo Audio decoder - channelsplit audio filter -- setnsamples audio filter -- atempo filter -- ffprobe -show_data option - RTMPT protocol support - iLBC encoding/decoding via libilbc - Microsoft Screen 1 decoder @@ -246,143 +116,44 @@ version 1.0: - Microsoft Expression Encoder Screen decoder - RTMPS protocol support - RTMPTS protocol support +- JPEG 2000 encoding support through OpenJPEG +- G.723.1 demuxer and decoder - RTMPE protocol support - RTMPTE protocol support -- showwaves and showspectrum filter -- LucasArts SMUSH playback support -- SAMI, RealText and SubViewer demuxers and decoders -- Heart Of Darkness PAF playback support -- iec61883 device -- asettb filter -- new option: -progress -- 3GPP Timed Text encoder/decoder -- GeoTIFF decoder support -- ffmpeg -(no)stdin option -- Opus decoder using libopus -- caca output device using libcaca -- alphaextract and alphamerge filters -- concat filter -- flite filter - Canopus Lossless Codec decoder -- bitmap subtitles in filters (experimental and temporary) -- MP2 encoding via TwoLAME -- bmp parser -- smptebars source -- asetpts filter -- hue filter -- ICO muxer -- SubRip encoder and decoder without embedded timing -- edge detection filter -- framestep filter -- ffmpeg -shortest option is now per-output file +- avconv -shortest option is now per-output file, -pass and -passlogfile are now per-output stream -- volume measurement filter - Ut Video encoder - Microsoft Screen 2 decoder -- smartblur filter ported from MPlayer -- CPiA decoder -- decimate filter ported from MPlayer - RTP depacketization of JPEG - Smooth Streaming live segmenter muxer -- F4V muxer -- sendcmd and asendcmd filters -- WebVTT demuxer and decoder (simple tags supported) - RTP packetization of JPEG -- faststart option in the MOV/MP4 muxer +- Opus decoder and encoder using libopus +- remove -same_quant, it hasn't worked for years - support for building with MSVC -version 0.11: +version 0.8: -- Fixes: CVE-2012-2772, CVE-2012-2774, CVE-2012-2775, CVE-2012-2776, CVE-2012-2777, - CVE-2012-2779, CVE-2012-2782, CVE-2012-2783, CVE-2012-2784, CVE-2012-2785, - CVE-2012-2786, CVE-2012-2787, CVE-2012-2788, CVE-2012-2789, CVE-2012-2790, - CVE-2012-2791, CVE-2012-2792, CVE-2012-2793, CVE-2012-2794, CVE-2012-2795, - CVE-2012-2796, CVE-2012-2797, CVE-2012-2798, CVE-2012-2799, CVE-2012-2800, - CVE-2012-2801, CVE-2012-2802, CVE-2012-2803, CVE-2012-2804, -- v408 Quicktime and Microsoft AYUV Uncompressed 4:4:4:4 encoder and decoder -- setfield filter -- CDXL demuxer and decoder -- Apple ProRes encoder -- ffprobe -count_packets and -count_frames options -- Sun Rasterfile Encoder -- ID3v2 attached pictures reading and writing -- WMA Lossless decoder -- bluray protocol -- blackdetect filter -- libutvideo encoder wrapper (--enable-libutvideo) -- swapuv filter -- bbox filter -- XBM encoder and decoder -- RealAudio Lossless decoder -- ZeroCodec decoder -- tile video filter -- Metal Gear Solid: The Twin Snakes demuxer -- OpenEXR image decoder -- removelogo filter -- drop support for ffmpeg without libavfilter -- drawtext video filter: fontconfig support -- ffmpeg -benchmark_all option -- super2xsai filter ported from libmpcodecs -- add libavresample audio conversion library for compatibility -- MicroDVD decoder -- Avid Meridien (AVUI) encoder and decoder -- accept + prefix to -pix_fmt option to disable automatic conversions. -- complete audio filtering in libavfilter and ffmpeg -- add fps filter -- vorbis parser -- png parser -- audio mix filter -- ffv1: support (draft) version 1.3 - - -version 0.10: - -- Fixes: CVE-2011-3929, CVE-2011-3934, CVE-2011-3935, CVE-2011-3936, - CVE-2011-3937, CVE-2011-3940, CVE-2011-3941, CVE-2011-3944, - CVE-2011-3945, CVE-2011-3946, CVE-2011-3947, CVE-2011-3949, - CVE-2011-3950, CVE-2011-3951, CVE-2011-3952 -- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder -- SBaGen (SBG) binaural beats script demuxer -- OpenMG Audio muxer -- Timecode extraction in DV and MOV -- thumbnail video filter -- XML output in ffprobe -- asplit audio filter -- tinterlace video filter -- astreamsync audio filter -- amerge audio filter -- ISMV (Smooth Streaming) muxer - GSM audio parser - SMJPEG muxer -- XWD encoder and decoder + + +version 0.8_beta2: + - Automatic thread count based on detection number of (available) CPU cores -- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder -- ffprobe -show_error option -- Avid 1:1 10-bit RGB Packer codec -- v308 Quicktime Uncompressed 4:4:4 encoder and decoder -- yuv4 libquicktime packed 4:2:0 encoder and decoder -- ffprobe -show_frames option -- silencedetect audio filter -- ffprobe -show_program_version, -show_library_versions, -show_versions options +- Deprecate libpostproc. If desired, the switch --enable-postproc will + enable it but it may be removed in a later Libav release. - rv34: frame-level multi-threading - optimized iMDCT transform on x86 using SSE for for mpegaudiodec -- Improved PGS subtitle decoder -- dumpgraph option to lavfi device -- r210 and r10k encoders -- ffwavesynth decoder -- aviocat tool -- ffeval tool -version 0.9: +version 0.8_beta1: -- openal input device added -- boxblur filter added - BWF muxer - Flash Screen Video 2 decoder -- lavfi input device added -- added avconv, which is almost the same for now, except +- ffplay/ffprobe/ffserver renamed to avplay/avprobe/avserver +- ffmpeg deprecated, added avconv, which is almost the same for now, except for a few incompatible changes in the options, which will hopefully make them easier to use. The changes are: * The options placement is now strictly enforced! While in theory the @@ -452,40 +223,23 @@ easier to use. The changes are: * -vframes/-aframes/-dframes options are now aliases to the new -frames option. * -vtag/-atag/-stag options are now aliases to the new -tag option. - XMV demuxer -- LOAS demuxer -- ashowinfo filter added - Windows Media Image decoder -- amovie source added - LATM muxer/demuxer -- Speex encoder via libspeex -- JSON output in ffprobe -- WTV muxer -- Optional C++ Support (needed for libstagefright) -- H.264 Decoding on Android via Stagefright -- Prores decoder -- BIN/XBIN/ADF/IDF text file decoder -- aconvert audio filter added -- audio support to lavfi input device added +- showinfo filter +- split filter - libcdio-paranoia input device for audio CD grabbing +- select filter - Apple ProRes decoder - CELT in Ogg demuxing -- G.723.1 demuxer and decoder -- libmodplug support (--enable-libmodplug) - VC-1 interlaced decoding -- libutvideo wrapper (--enable-libutvideo) -- aevalsrc audio source added +- lut, lutrgb, and lutyuv filters +- boxblur filter - Ut Video decoder - Speex encoding via libspeex - 4:2:2 H.264 decoding support - 4:2:2 and 4:4:4 H.264 encoding with libx264 - Pulseaudio input device -- Prores encoder -- Video Decoder Acceleration (VDA) HWAccel module. - replacement Indeo 3 decoder -- new ffmpeg option: -map_channel -- volume audio filter added -- earwax audio filter added -- libv4l2 support (--enable-libv4l2) - TLS/SSL and HTTPS protocol support - AVOptions API rewritten and documented - most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in @@ -495,27 +249,44 @@ easier to use. The changes are: - Discworld II BMV decoding support - VBLE Decoder - OS X Video Decoder Acceleration (VDA) support -- compact and csv output in ffprobe -- pan audio filter -- IFF Amiga Continuous Bitmap (ACBM) decoder -- ass filter - CRI ADX audio format muxer and demuxer - Playstation Portable PMP format demuxer -- Microsoft Windows ICO demuxer -- life source - PCM format support in OMA demuxer - CLJR encoder -- new option: -report - Dxtory capture format decoder -- cellauto source +- v410 QuickTime uncompressed 4:4:4 10-bit encoder and decoder +- OpenMG Audio muxer - Simple segmenting muxer - Indeo 4 decoder - SMJPEG demuxer -version 0.8: +version 0.7: + +- E-AC-3 audio encoder +- ac3enc: add channel coupling support +- floating-point sample format support for (E-)AC-3, DCA, AAC, Vorbis decoders +- H.264/MPEG frame-level multithreading +- 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 +- bump libswscale for recently reported ABI break + + +version 0.7_beta2: + +- VP8 frame-level multithreading +- NEON optimizations for VP8 +- removed a lot of deprecated API cruft +- FFT and IMDCT optimizations for AVX (Sandy Bridge) processors +- DPX image encoder +- SMPTE 302M AES3 audio decoder +- ffmpeg no longer quits after the 'q' key is pressed; use 'ctrl+c' instead +- 9bit and 10bit per sample support in the H.264 decoder + + +version 0.7_beta1: -- 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 @@ -523,7 +294,6 @@ version 0.8: - Demuxer for On2's IVF format - Pictor/PC Paint decoder - HE-AAC v2 decoder -- HE-AAC v2 encoding with libaacplus - libfaad2 wrapper removed - DTS-ES extension (XCh) decoding support - native VP8 decoder @@ -535,7 +305,6 @@ version 0.8: - 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 @@ -582,7 +351,7 @@ version 0.8: - 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 +- SubRip (srt) subtitle decoder - floating-point AC-3 encoder added - Lagarith decoder - ffmpeg -copytb option added @@ -595,46 +364,11 @@ version 0.8: - 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 +- Mobotix MxPEG decoder - AAC encoding via libvo-aacenc - AMR-WB encoding via libvo-amrwbenc - xWMA demuxer -- Mobotix MxPEG decoder -- VP8 frame-multithreading -- NEON optimizations for VP8 -- Lots of deprecated API cruft removed -- fft and imdct optimizations for AVX (Sandy Bridge) processors -- showinfo filter added -- SMPTE 302M AES3 audio decoder -- Apple Core Audio Format muxer -- 9bit and 10bit per sample support in the H.264 decoder -- 9bit and 10bit FFV1 encoding / decoding -- split filter added -- select filter added -- sdl output device added -- libmpcodecs video filter support (3 times as many filters than before) -- mpeg2 aspect ratio dection fixed -- libxvid aspect pickiness fixed -- Frame multithreaded decoding -- E-AC-3 audio encoder -- ac3enc: add channel coupling support -- floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders. -- H264/MPEG frame-level multi-threading -- All av_metadata_* functions renamed to av_dict_* and moved to libavutil -- 4:4:4 H.264 decoding support -- 10-bit H.264 optimizations for x86 -- lut, lutrgb, and lutyuv filters added -- buffersink libavfilter sink added -- Bump libswscale for recently reported ABI break -- New J2K encoder (via OpenJPEG) - - -version 0.7: - -- all the changes for 0.8, but keeping API/ABI compatibility with the 0.6 release +- fieldorder video filter added version 0.6: @@ -875,7 +609,6 @@ version 0.5: - Gopher client support - MXF D-10 muxer - generic metadata API -- flash ScreenVideo2 encoder version 0.4.9-pre1: @@ -1078,7 +811,7 @@ version 0.4.5: - MPEG-4 vol header fixes (Jonathan Marsden ) - ARM optimizations (Lionel Ulmer ). - Windows porting of file converter -- added MJPEG raw format (input/output) +- added MJPEG raw format (input/ouput) - added JPEG image format support (input/output) diff --git a/INSTALL b/INSTALL index 9549346302..ac5dc5dbb6 100644 --- a/INSTALL +++ b/INSTALL @@ -2,14 +2,17 @@ 1) Type './configure' to create the configuration. A list of configure options is printed by running 'configure --help'. -'configure' can be launched from a directory different from the FFmpeg +'configure' can be launched from a directory different from the Libav sources to build the objects out of tree. To do this, use an absolute -path when launching 'configure', e.g. '/ffmpegdir/ffmpeg/configure'. +path when launching 'configure', e.g. '/libavdir/libav/configure'. -2) Then type 'make' to build FFmpeg. GNU Make 3.81 or later is required. +2) Then type 'make' to build Libav. GNU Make 3.81 or later is required. 3) Type 'make install' to install all binaries and libraries you built. NOTICE - Non system dependencies (e.g. libx264, libvpx) are disabled by default. + + - The default cflags include -g, if you want lean libraries you can either + pass --disable-debug or strip the debug symbols at a later time. diff --git a/LICENSE b/LICENSE index 1840d69179..1074989bfc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,54 +1,27 @@ -FFmpeg: +Libav: +====== -Most files in FFmpeg are under the GNU Lesser General Public License version 2.1 +Most files in Libav are under the GNU Lesser General Public License version 2.1 or later (LGPL v2.1+). Read the file COPYING.LGPLv2.1 for details. Some other files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to -FFmpeg. +Libav. -Some optional parts of FFmpeg are licensed under the GNU General Public License +Some optional parts of Libav are licensed under the GNU General Public License version 2 or later (GPL v2+). See the file COPYING.GPLv2 for details. None of these parts are used by default, you have to explicitly pass --enable-gpl to -configure to activate them. In this case, FFmpeg's license changes to GPL v2+. +configure to activate them. In this case, Libav's license changes to GPL v2+. -Specifically, the GPL parts of FFmpeg are +Specifically, the GPL parts of Libav are -- libpostproc -- libmpcodecs -- optional x86 optimizations in the files - libavcodec/x86/idct_mmx.c -- libutvideo encoding/decoding wrappers in - libavcodec/libutvideo*.cpp - the X11 grabber in libavdevice/x11grab.c -- the swresample test app in - libswresample/swresample-test.c - the texi2pod.pl tool - the following filters in libavfilter: - - f_ebur128.c - vf_blackframe.c - vf_boxblur.c - - vf_colormatrix.c - vf_cropdetect.c - - vf_decimate.c - vf_delogo.c - - vf_geq.c - - vf_histeq.c - vf_hqdn3d.c - - vf_kerndeint.c - - vf_mcdeint.c - - vf_mp.c - - vf_owdenoise.c - - vf_perspective.c - - vf_phase.c - - vf_pp.c - - vf_pullup.c - - vf_sab.c - - vf_smartblur.c - - vf_spp.c - - vf_stereo3d.c - - vf_super2xsai.c - - vf_tinterlace.c - vf_yadif.c - - vsrc_mptestsrc.c Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then the configure parameter --enable-version3 will activate this licensing option @@ -68,36 +41,26 @@ There are a handful of files under other licensing terms, namely: external libraries ================== -FFmpeg can be combined with a number of external libraries, which sometimes +Libav can be combined with a number of external libraries, which sometimes affect the licensing of binaries resulting from the combination. compatible libraries -------------------- -The following libraries are under GPL: - - frei0r - - libcdio - - libutvideo - - libvidstab - - libx264 - - libxavs - - libxvid -When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by +The libcdio, libx264, libxavs and libxvid libraries are under GPL. When +combining them with Libav, Libav needs to be licensed as GPL as well by passing --enable-gpl to configure. The OpenCORE and VisualOn libraries are under the Apache License 2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with -version 3 of those licenses. So to combine these libraries with FFmpeg, the +version 3 of those licenses. So to combine these libraries with Libav, the license version needs to be upgraded by passing --enable-version3 to configure. incompatible libraries ---------------------- -The Fraunhofer AAC library, FAAC and aacplus are under licenses which -are incompatible with the GPLv2 and v3. We do not know for certain if their -licenses are compatible with the LGPL. -If you wish to enable these libraries, pass --enable-nonfree to configure. -But note that if you enable any of these libraries the resulting binary will -be under a complex license mix that is more restrictive than the LGPL and that -may result in additional obligations. It is possible that these -restrictions cause the resulting binary to be unredistributeable. +The Fraunhofer AAC library, FAAC and OpenSSL are under licenses incompatible +with all (L)GPL versions. Thus, unfortunately, since both licenses cannot be +satisfied simultaneously, binaries resulting from the combination of Libav +with these libraries are nonfree und unredistributable. If you wish to enable +any of these libraries nonetheless, pass --enable-nonfree to configure. diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index ebfb735886..0000000000 --- a/MAINTAINERS +++ /dev/null @@ -1,547 +0,0 @@ -FFmpeg maintainers -================== - -Below is a list of the people maintaining different parts of the -FFmpeg code. - -Please try to keep entries where you are the maintainer up to date! - -Names in () mean that the maintainer currently has no time to maintain the code. -A (CC
) after the name means that the maintainer prefers to be CC-ed on -patches and related discussions. - - -Project Leader -============== - -Michael Niedermayer - final design decisions - - -Applications -============ - -ffmpeg: - ffmpeg.c Michael Niedermayer - -ffplay: - ffplay.c Marton Balint - -ffprobe: - ffprobe.c Stefano Sabatini - -Commandline utility code: - cmdutils.c, cmdutils.h Michael Niedermayer - -QuickTime faststart: - tools/qt-faststart.c Baptiste Coudurier - - -Miscellaneous Areas -=================== - -documentation Stefano Sabatini, Mike Melanson, Timothy Gu -build system (configure,Makefiles) Diego Biurrun, Mans Rullgard -project server Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger, Alexander Strasser -presets Robert Swain -metadata subsystem Aurelien Jacobs -release management Michael Niedermayer - - -Communication -============= - -website Robert Swain, Lou Logan -mailinglists Michael Niedermayer, Baptiste Coudurier, Lou Logan -Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser -Twitter Lou Logan -Launchpad Timothy Gu - - -libavutil -========= - -External Interfaces: - libavutil/avutil.h Michael Niedermayer -Internal Interfaces: - libavutil/common.h Michael Niedermayer - -Other: - bprint Nicolas George - bswap.h - des Reimar Doeffinger - eval.c, eval.h Michael Niedermayer - float_dsp Loren Merritt - hash Reimar Doeffinger - intfloat* Michael Niedermayer - integer.c, integer.h Michael Niedermayer - lzo Reimar Doeffinger - mathematics.c, mathematics.h Michael Niedermayer - mem.c, mem.h Michael Niedermayer - opencl.c, opencl.h Wei Gao - opt.c, opt.h Michael Niedermayer - rational.c, rational.h Michael Niedermayer - rc4 Reimar Doeffinger - ripemd.c, ripemd.h James Almer - timecode Clément Bœsch - - -libavcodec -========== - -Generic Parts: - External Interfaces: - avcodec.h Michael Niedermayer - utility code: - utils.c Michael Niedermayer - audio and video frame extraction: - parser.c Michael Niedermayer - bitstream reading: - bitstream.c, bitstream.h Michael Niedermayer - CABAC: - cabac.h, cabac.c Michael Niedermayer - codec names: - codec_names.sh Nicolas George - DSP utilities: - dsputils.c, dsputils.h Michael Niedermayer - entropy coding: - rangecoder.c, rangecoder.h Michael Niedermayer - lzw.* Michael Niedermayer - floating point AAN DCT: - faandct.c, faandct.h Michael Niedermayer - Golomb coding: - golomb.c, golomb.h Michael Niedermayer - LPC: - lpc.c, lpc.h Justin Ruggles - motion estimation: - motion* Michael Niedermayer - rate control: - ratecontrol.c Michael Niedermayer - libxvid_rc.c Michael Niedermayer - simple IDCT: - simple_idct.c, simple_idct.h Michael Niedermayer - postprocessing: - libpostproc/* Michael Niedermayer - table generation: - tableprint.c, tableprint.h Reimar Doeffinger - fixed point FFT: - fft* Zeljko Lukac - -Codecs: - 4xm.c Michael Niedermayer - 8bps.c Roberto Togni - 8svx.c Jaikrishnan Menon - aasc.c Kostya Shishkov - ac3* Justin Ruggles - alacenc.c Jaikrishnan Menon - alsdec.c Thilo Borgmann - apedec.c Kostya Shishkov - ass* Aurelien Jacobs - asv* Michael Niedermayer - atrac3* Benjamin Larsson - atrac3plus* Maxim Poliakovski - bgmc.c, bgmc.h Thilo Borgmann - bink.c Kostya Shishkov - binkaudio.c Peter Ross - bmp.c Mans Rullgard, Kostya Shishkov - cavs* Stefan Gehrer - cdxl.c Paul B Mahol - celp_filters.* Vitor Sessak - cinepak.c Roberto Togni - cljr Alex Beregszaszi - cllc.c Derek Buitenhuis - cook.c, cookdata.h Benjamin Larsson - cpia.c Stephan Hilb - crystalhd.c Philip Langdale - cscd.c Reimar Doeffinger - dca.c Kostya Shishkov, Benjamin Larsson - dnxhd* Baptiste Coudurier - dpcm.c Mike Melanson - dv.c Roman Shaposhnik - dxa.c Kostya Shishkov - eacmv*, eaidct*, eat* Peter Ross - exif.c, exif.h Thilo Borgmann - ffv1.c Michael Niedermayer - ffwavesynth.c Nicolas George - flac* Justin Ruggles - flashsv* Benjamin Larsson - flicvideo.c Mike Melanson - g722.c Martin Storsjo - g726.c Roman Shaposhnik - gifdec.c Baptiste Coudurier - h261* Michael Niedermayer - h263* Michael Niedermayer - h264* Loren Merritt, Michael Niedermayer - huffyuv.c Michael Niedermayer - idcinvideo.c Mike Melanson - imc* Benjamin Larsson - indeo2* Kostya Shishkov - indeo5* Kostya Shishkov - interplayvideo.c Mike Melanson - ivi* Kostya Shishkov - jacosub* Clément Bœsch - jpeg2000* Nicolas Bertrand - jpeg_ls.c Kostya Shishkov - jvdec.c Peter Ross - kmvc.c Kostya Shishkov - lcl*.c Roberto Togni, Reimar Doeffinger - libcelt_dec.c Nicolas George - libdirac* David Conrad - libgsm.c Michel Bardiaux - libopenjpeg.c Jaikrishnan Menon - libopenjpegenc.c Michael Bradshaw - libschroedinger* David Conrad - libspeexdec.c Justin Ruggles - libtheoraenc.c David Conrad - libutvideo* Derek Buitenhuis - libvorbis.c David Conrad - libvpx* James Zern - libx264.c Mans Rullgard, Jason Garrett-Glaser - libxavs.c Stefan Gehrer - libzvbi-teletextdec.c Marton Balint - loco.c Kostya Shishkov - lzo.h, lzo.c Reimar Doeffinger - mdec.c Michael Niedermayer - mimic.c Ramiro Polla - mjpeg*.c Michael Niedermayer - mlp* Ramiro Polla - mmvideo.c Peter Ross - mpc* Kostya Shishkov - mpeg12.c, mpeg12data.h Michael Niedermayer - mpegvideo.c, mpegvideo.h Michael Niedermayer - mqc* Nicolas Bertrand - msmpeg4.c, msmpeg4data.h Michael Niedermayer - msrle.c Mike Melanson - msvideo1.c Mike Melanson - nellymoserdec.c Benjamin Larsson - nuv.c Reimar Doeffinger - paf.* Paul B Mahol - pcx.c Ivo van Poorten - pgssubdec.c Reimar Doeffinger - ptx.c Ivo van Poorten - qcelp* Reynaldo H. Verdejo Pinochet - qdm2.c, qdm2data.h Roberto Togni, Benjamin Larsson - qdrw.c Kostya Shishkov - qpeg.c Kostya Shishkov - qtrle.c Mike Melanson - ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni - resample2.c Michael Niedermayer - rl2.c Sascha Sommer - rpza.c Roberto Togni - rtjpeg.c, rtjpeg.h Reimar Doeffinger - rv10.c Michael Niedermayer - rv3* Kostya Shishkov - rv4* Kostya Shishkov - s3tc* Ivo van Poorten - smacker.c Kostya Shishkov - smc.c Mike Melanson - smvjpegdec.c Ash Hughes - snow.c Michael Niedermayer, Loren Merritt - sonic.c Alex Beregszaszi - srt* Aurelien Jacobs - sunrast.c Ivo van Poorten - svq3.c Michael Niedermayer - tak* Paul B Mahol - targa.c Kostya Shishkov - tiff.c Kostya Shishkov - truemotion1* Mike Melanson - truemotion2* Kostya Shishkov - truespeech.c Kostya Shishkov - tscc.c Kostya Shishkov - tta.c Alex Beregszaszi, Jaikrishnan Menon - ttaenc.c Paul B Mahol - txd.c Ivo van Poorten - ulti* Kostya Shishkov - v410*.c Derek Buitenhuis - vb.c Kostya Shishkov - vble.c Derek Buitenhuis - vc1* Kostya Shishkov - vcr1.c Michael Niedermayer - vda_h264_dec.c Xidorn Quan - vima.c Paul B Mahol - vmnc.c Kostya Shishkov - vorbis_dec.c Denes Balatoni, David Conrad - vorbis_enc.c Oded Shimon - vp3* Mike Melanson - vp5 Aurelien Jacobs - vp6 Aurelien Jacobs - vp8 David Conrad, Jason Garrett-Glaser, Ronald Bultje - vp9 Ronald Bultje, Clément Bœsch - vqavideo.c Mike Melanson - wavpack.c Kostya Shishkov - wmaprodec.c Sascha Sommer - wmavoice.c Ronald S. Bultje - wmv2.c Michael Niedermayer - wnv1.c Kostya Shishkov - xan.c Mike Melanson - xbm* Paul B Mahol - xface Stefano Sabatini - xl.c Kostya Shishkov - xvmc.c Ivan Kalvachev - xwd* Paul B Mahol - zerocodec.c Derek Buitenhuis - zmbv* Kostya Shishkov - -Hardware acceleration: - crystalhd.c Philip Langdale - dxva2* Laurent Aimar - libstagefright.cpp Mohamed Naufal - vaapi* Gwenole Beauchesne - vda* Sebastien Zwickert - vdpau* Carl Eugen Hoyos - - -libavdevice -=========== - External Interface: - libavdevice/avdevice.h - - - dshow.c Roger Pack - fbdev_enc.c Lukasz Marek - iec61883.c Georg Lippitsch - lavfi Stefano Sabatini - libdc1394.c Roman Shaposhnik - pulse_audio_enc.c Lukasz Marek - sdl Stefano Sabatini - v4l2.c Luca Abeni - vfwcap.c Ramiro Polla - -libavfilter -=========== - -Generic parts: - graphdump.c Nicolas George - -Filters: - af_adelay.c Paul B Mahol - af_aecho.c Paul B Mahol - af_afade.c Paul B Mahol - af_amerge.c Nicolas George - af_aphaser.c Paul B Mahol - af_aresample.c Michael Niedermayer - af_astats.c Paul B Mahol - af_astreamsync.c Nicolas George - af_atempo.c Pavel Koshevoy - af_biquads.c Paul B Mahol - af_compand.c Paul B Mahol - af_ladspa.c Paul B Mahol - af_pan.c Nicolas George - avf_avectorscope.c Paul B Mahol - vf_blend.c Paul B Mahol - vf_colorbalance.c Paul B Mahol - vf_delogo.c Jean Delvare (CC ) - vf_drawbox.c/drawgrid Andrey Utkin - vf_extractplanes.c Paul B Mahol - vf_histogram.c Paul B Mahol - vf_il.c Paul B Mahol - vf_mergeplanes.c Paul B Mahol - vf_psnr.c Paul B Mahol - vf_scale.c Michael Niedermayer - vf_separatefields.c Paul B Mahol - vf_stereo3d.c Paul B Mahol - vf_telecine.c Paul B Mahol - vf_yadif.c Michael Niedermayer - -Sources: - vsrc_mandelbrot.c Michael Niedermayer - -libavformat -=========== - -Generic parts: - External Interface: - libavformat/avformat.h Michael Niedermayer - Utility Code: - libavformat/utils.c Michael Niedermayer - - -Muxers/Demuxers: - 4xm.c Mike Melanson - adtsenc.c Robert Swain - afc.c Paul B Mahol - aiffdec.c Baptiste Coudurier, Matthieu Bouron - aiffenc.c Baptiste Coudurier, Matthieu Bouron - ape.c Kostya Shishkov - ass* Aurelien Jacobs - astdec.c Paul B Mahol - astenc.c James Almer - avi* Michael Niedermayer - avisynth.c AvxSynth Team (avxsynth.testing at gmail dot com) - avr.c Paul B Mahol - bink.c Peter Ross - brstm.c Paul B Mahol - caf* Peter Ross - cdxl.c Paul B Mahol - crc.c Michael Niedermayer - daud.c Reimar Doeffinger - dtshddec.c Paul B Mahol - dv.c Roman Shaposhnik - dxa.c Kostya Shishkov - electronicarts.c Peter Ross - epafdec.c Paul B Mahol - ffm* Baptiste Coudurier - flac* Justin Ruggles - flic.c Mike Melanson - flvdec.c, flvenc.c Michael Niedermayer - gxf.c Reimar Doeffinger - gxfenc.c Baptiste Coudurier - hls.c Anssi Hannula - idcin.c Mike Melanson - idroqdec.c Mike Melanson - iff.c Jaikrishnan Menon - img2*.c Michael Niedermayer - ipmovie.c Mike Melanson - ircam* Paul B Mahol - iss.c Stefan Gehrer - jacosub* Clément Bœsch - jvdec.c Peter Ross - libmodplug.c Clément Bœsch - libnut.c Oded Shimon - lmlm4.c Ivo van Poorten - lvfdec.c Paul B Mahol - lxfdec.c Tomas Härdin - matroska.c Aurelien Jacobs - matroskadec.c Aurelien Jacobs - matroskaenc.c David Conrad - metadata* Aurelien Jacobs - mgsts.c Paul B Mahol - microdvd* Aurelien Jacobs - mm.c Peter Ross - mov.c Michael Niedermayer, Baptiste Coudurier - movenc.c Baptiste Coudurier, Matthieu Bouron - mpc.c Kostya Shishkov - mpeg.c Michael Niedermayer - mpegenc.c Michael Niedermayer - mpegts* Baptiste Coudurier - msnwc_tcp.c Ramiro Polla - mtv.c Reynaldo H. Verdejo Pinochet - mxf* Baptiste Coudurier - mxfdec.c Tomas Härdin - nistspheredec.c Paul B Mahol - nsvdec.c Francois Revol - nut.c Michael Niedermayer - nuv.c Reimar Doeffinger - oggdec.c, oggdec.h David Conrad - oggenc.c Baptiste Coudurier - oggparse*.c David Conrad - oma.c Maxim Poliakovski - paf.c Paul B Mahol - psxstr.c Mike Melanson - pva.c Ivo van Poorten - pvfdec.c Paul B Mahol - r3d.c Baptiste Coudurier - raw.c Michael Niedermayer - rdt.c Ronald S. Bultje - rl2.c Sascha Sommer - rmdec.c, rmenc.c Ronald S. Bultje, Kostya Shishkov - rtmp* Kostya Shishkov - rtp.c, rtpenc.c Martin Storsjo - rtpdec_asf.* Ronald S. Bultje - rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo - rtsp.c Luca Barbato - sbgdec.c Nicolas George - sdp.c Martin Storsjo - segafilm.c Mike Melanson - siff.c Kostya Shishkov - smacker.c Kostya Shishkov - smjpeg* Paul B Mahol - spdif* Anssi Hannula - srtdec.c Aurelien Jacobs - swf.c Baptiste Coudurier - takdec.c Paul B Mahol - tta.c Alex Beregszaszi - txd.c Ivo van Poorten - voc.c Aurelien Jacobs - wav.c Michael Niedermayer - wc3movie.c Mike Melanson - webvtt* Matthew J Heaney - westwood.c Mike Melanson - wtv.c Peter Ross - wv.c Kostya Shishkov - wvenc.c Paul B Mahol - -Protocols: - bluray.c Petri Hintukainen - ftp.c Lukasz Marek - http.c Ronald S. Bultje - libssh.c Lukasz Marek - mms*.c Ronald S. Bultje - udp.c Luca Abeni - - -libswresample -============= - -Generic parts: - audioconvert.c Michael Niedermayer - dither.c Michael Niedermayer - rematrix*.c Michael Niedermayer - swresample*.c Michael Niedermayer - -Resamplers: - resample*.c Michael Niedermayer - soxr_resample.c Rob Sykes - - -Operating systems / CPU architectures -===================================== - -Alpha Mans Rullgard, Falk Hueffner -ARM Mans Rullgard -AVR32 Mans Rullgard -MIPS Mans Rullgard, Nedeljko Babic -Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier -Amiga / PowerPC Colin Ward -Linux / PowerPC Luca Barbato -Windows MinGW Alex Beregszaszi, Ramiro Polla -Windows Cygwin Victor Paesa -ADI/Blackfin DSP Marc Hoffman -Sparc Roman Shaposhnik -x86 Michael Niedermayer - - -Releases -======== - -2.1 Michael Niedermayer -1.2 Michael Niedermayer - -If you want to maintain an older release, please contact us - - -GnuPG Fingerprints of maintainers and contributors -================================================== - -Alexander Strasser 1C96 78B7 83CB 8AA7 9AF5 D1EB A7D8 A57B A876 E58F -Anssi Hannula 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB -Anton Khirnov 6D0C 6625 56F8 65D1 E5F5 814B B50A 1241 C067 07AB -Ash Hughes 694D 43D2 D180 C7C7 6421 ABD3 A641 D0B7 623D 6029 -Attila Kinali 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765 -Baptiste Coudurier 8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA -Ben Littler 3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C -Benoit Fouet B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8 -Bœsch Clément 52D0 3A82 D445 F194 DB8B 2B16 87EE 2CB8 F4B8 FCF9 -Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7 -Diego Biurrun 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5 -FFmpeg release signing key FCF9 86EA 15E6 E293 A564 4F10 B432 2F04 D676 58D8 -Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4 -Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368 -Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A -Justin Ruggles 3136 ECC0 C10D 6C04 5F43 CA29 FCBE CD2A 3787 1EBF -Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE -Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A -Luca Barbato 6677 4209 213C 8843 5B67 29E7 E84C 78C2 84E9 0E34 -Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB -Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93 -Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029 -Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B -Reimar Döffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7 -Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4 -Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A -Robert Swain EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71 -Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C -Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F -Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863 -Tomas Härdin A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551 -Wei Gao 4269 7741 857A 0E60 9EC5 08D2 4744 4EFA 62C1 87B9 diff --git a/Makefile b/Makefile index 7317f254fb..25c3b32d40 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,82 @@ -MAIN_MAKEFILE=1 include config.mak vpath %.c $(SRC_PATH) -vpath %.cpp $(SRC_PATH) vpath %.h $(SRC_PATH) vpath %.S $(SRC_PATH) vpath %.asm $(SRC_PATH) -vpath %.rc $(SRC_PATH) vpath %.v $(SRC_PATH) vpath %.texi $(SRC_PATH) -vpath %/fate_config.sh.template $(SRC_PATH) -AVPROGS-$(CONFIG_FFMPEG) += ffmpeg -AVPROGS-$(CONFIG_FFPLAY) += ffplay -AVPROGS-$(CONFIG_FFPROBE) += ffprobe -AVPROGS-$(CONFIG_FFSERVER) += ffserver +ifndef V +Q = @ +ECHO = printf "$(1)\t%s\n" $(2) +BRIEF = CC HOSTCC HOSTLD AS YASM AR LD +SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM STRIP +MSG = $@ +M = @$(call ECHO,$(TAG),$@); +$(foreach VAR,$(BRIEF), \ + $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR)))) +$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR)))) +$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_PATH)/%=%)); $(INSTALL)) +endif -AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF)) -INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF)) +ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil swscale + +IFLAGS := -I. -I$(SRC_PATH) +CPPFLAGS := $(IFLAGS) $(CPPFLAGS) +CFLAGS += $(ECFLAGS) +CCFLAGS = $(CPPFLAGS) $(CFLAGS) +ASFLAGS := $(CPPFLAGS) $(ASFLAGS) +YASMFLAGS += $(IFLAGS:%=%/) -Pconfig.asm +HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS) +LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS) + +define COMPILE + $(call $(1)DEP,$(1)) + $($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $< +endef + +COMPILE_C = $(call COMPILE,CC) +COMPILE_S = $(call COMPILE,AS) +COMPILE_HOSTC = $(call COMPILE,HOSTCC) + +%.o: %.c + $(COMPILE_C) + +%.o: %.S + $(COMPILE_S) + +%_host.o: %.c + $(COMPILE_HOSTC) + +%.i: %.c + $(CC) $(CCFLAGS) $(CC_E) $< + +%.h.c: + $(Q)echo '#include "$*.h"' >$@ + +%.ver: %.v + $(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@ + +%.c %.h: TAG = GEN + +AVPROGS-$(CONFIG_AVCONV) += avconv +AVPROGS-$(CONFIG_AVPLAY) += avplay +AVPROGS-$(CONFIG_AVPROBE) += avprobe +AVPROGS-$(CONFIG_AVSERVER) += avserver + +AVPROGS := $(AVPROGS-yes:%=%$(EXESUF)) PROGS += $(AVPROGS) -AVBASENAMES = ffmpeg ffplay ffprobe ffserver -ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF)) -ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF)) +AVBASENAMES = avconv avplay avprobe avserver +ALLAVPROGS = $(AVBASENAMES:%=%$(EXESUF)) $(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o)) -$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_opencl.o)) -OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o -OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o -TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 +OBJS-avconv += avconv_opt.o avconv_filter.o +OBJS-avconv-$(HAVE_VDPAU_X11) += avconv_vdpau.o + +TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64 HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options TOOLS = qt-faststart trasher TOOLS-$(CONFIG_ZLIB) += cws2fws @@ -39,14 +86,11 @@ FFLIBS-$(CONFIG_AVFILTER) += avfilter FFLIBS-$(CONFIG_AVFORMAT) += avformat FFLIBS-$(CONFIG_AVRESAMPLE) += avresample FFLIBS-$(CONFIG_AVCODEC) += avcodec -FFLIBS-$(CONFIG_POSTPROC) += postproc -FFLIBS-$(CONFIG_SWRESAMPLE)+= swresample FFLIBS-$(CONFIG_SWSCALE) += swscale FFLIBS := avutil -DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd -EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile $(SRC_PATH)/doc/examples/README +DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset) SKIPHEADERS = cmdutils_common_opts.h compat/w32pthreads.h @@ -73,8 +117,7 @@ SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \ ARMV5TE-OBJS ARMV6-OBJS VFP-OBJS NEON-OBJS \ ALTIVEC-OBJS VIS-OBJS \ MMX-OBJS YASM-OBJS \ - MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS \ - OBJS SLIBOBJS HOSTOBJS TESTOBJS + OBJS HOSTOBJS TESTOBJS define RESET $(1) := @@ -95,22 +138,16 @@ include $(SRC_PATH)/doc/Makefile define DOPROG OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes) -$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1)) +$(1)$(EXESUF): $$(OBJS-$(1)) $$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) -$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) -$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1)) +$(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) +$(1)$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1)) -include $$(OBJS-$(1):.o=.d) endef -$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=)))) +$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(EXESUF)=)))) -ffprobe.o cmdutils.o : libavutil/ffversion.h - -$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) - $(CP) $< $@ - $(STRIP) $@ - -%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS) +$(PROGS): %$(EXESUF): %.o $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) OBJDIRS += tools @@ -123,8 +160,8 @@ GIT_LOG = $(SRC_PATH)/.git/logs/HEAD .version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak .version: M=@ -libavutil/ffversion.h .version: - $(M)$(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION) +version.h .version: + $(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION) $(Q)touch .version # force version.sh to run whenever version might have changed @@ -143,12 +180,11 @@ install-progs-$(CONFIG_SHARED): install-libs install-progs: install-progs-yes $(AVPROGS) $(Q)mkdir -p "$(BINDIR)" - $(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)" + $(INSTALL) -c -m 755 $(AVPROGS) "$(BINDIR)" -install-data: $(DATA_FILES) $(EXAMPLES_FILES) - $(Q)mkdir -p "$(DATADIR)/examples" +install-data: $(DATA_FILES) + $(Q)mkdir -p "$(DATADIR)" $(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)" - $(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples" uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data @@ -159,20 +195,19 @@ uninstall-data: $(RM) -r "$(DATADIR)" clean:: - $(RM) $(ALLAVPROGS) $(ALLAVPROGS_G) + $(RM) $(ALLAVPROGS) $(RM) $(CLEANSUFFIXES) $(RM) $(CLEANSUFFIXES:%=tools/%) - $(RM) -r coverage-html $(RM) -rf coverage.info lcov distclean:: $(RM) $(DISTCLEANSUFFIXES) - $(RM) config.* .config libavutil/avconfig.h .version version.h libavutil/ffversion.h libavcodec/codec_names.h + $(RM) config.* .config libavutil/avconfig.h .version version.h config: - $(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION) + $(SRC_PATH)/configure $(value LIBAV_CONFIGURATION) -check: all alltools examples testprogs fate +check: all alltools checkheaders examples testprogs fate include $(SRC_PATH)/tests/Makefile @@ -187,5 +222,5 @@ $(sort $(OBJDIRS)): # so this saves some time on slow systems. .SUFFIXES: -.PHONY: all all-yes alltools check *clean config install* +.PHONY: all all-yes alltools check *clean config examples install* .PHONY: testprogs uninstall* diff --git a/README b/README index ae007bcccf..afef671611 100644 --- a/README +++ b/README @@ -1,18 +1,12 @@ -FFmpeg README -------------- +Libav README +------------ 1) Documentation ---------------- -* Read the documentation in the doc/ directory in git. - You can also view it online at http://ffmpeg.org/documentation.html +* Read the documentation in the doc/ directory. 2) Licensing ------------ * See the LICENSE file. - -3) Build and Install --------------------- - -* See the INSTALL file. diff --git a/RELEASE b/RELEASE index 7f9e2dc607..ae33bab0e8 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -2.1.git +10_alpha1 diff --git a/arch.mak b/arch.mak index b71c8e51f3..09d24af49a 100644 --- a/arch.mak +++ b/arch.mak @@ -3,11 +3,6 @@ OBJS-$(HAVE_ARMV6) += $(ARMV6-OBJS) $(ARMV6-OBJS-yes) OBJS-$(HAVE_VFP) += $(VFP-OBJS) $(VFP-OBJS-yes) OBJS-$(HAVE_NEON) += $(NEON-OBJS) $(NEON-OBJS-yes) -OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes) -OBJS-$(HAVE_MIPS32R2) += $(MIPS32R2-OBJS) $(MIPS32R2-OBJS-yes) -OBJS-$(HAVE_MIPSDSPR1) += $(MIPSDSPR1-OBJS) $(MIPSDSPR1-OBJS-yes) -OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes) - OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes) OBJS-$(HAVE_VIS) += $(VIS-OBJS) $(VIS-OBJS-yes) diff --git a/ffmpeg.c b/avconv.c similarity index 50% rename from ffmpeg.c rename to avconv.c index 5ccbf10012..17dc468f6b 100644 --- a/ffmpeg.c +++ b/avconv.c @@ -1,49 +1,38 @@ /* - * Copyright (c) 2000-2003 Fabrice Bellard + * avconv main + * Copyright (c) 2000-2011 The libav developers. * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * 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. * - * FFmpeg is distributed in the hope that it will be useful, + * 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/** - * @file - * multimedia converter based on the FFmpeg libraries - */ - #include "config.h" #include #include #include #include #include +#include #include #include -#if HAVE_ISATTY -#if HAVE_IO_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#endif - #include "libavformat/avformat.h" #include "libavdevice/avdevice.h" -#include "libswresample/swresample.h" +#include "libswscale/swscale.h" +#include "libavresample/avresample.h" #include "libavutil/opt.h" #include "libavutil/channel_layout.h" #include "libavutil/parseutils.h" @@ -56,14 +45,9 @@ #include "libavutil/avstring.h" #include "libavutil/libm.h" #include "libavutil/imgutils.h" -#include "libavutil/timestamp.h" -#include "libavutil/bprint.h" #include "libavutil/time.h" #include "libavformat/os_support.h" -#include "libavformat/ffm.h" // not public API - -# include "libavfilter/avcodec.h" # include "libavfilter/avfilter.h" # include "libavfilter/buffersrc.h" # include "libavfilter/buffersink.h" @@ -84,64 +68,36 @@ #include #endif -#if HAVE_TERMIOS_H -#include -#include -#include -#include -#elif HAVE_KBHIT -#include -#endif - #if HAVE_PTHREADS #include #endif #include -#include "ffmpeg.h" +#include "avconv.h" #include "cmdutils.h" #include "libavutil/avassert.h" -const char program_name[] = "ffmpeg"; +const char program_name[] = "avconv"; const int program_birth_year = 2000; static FILE *vstats_file; -const char *const forced_keyframes_const_names[] = { - "n", - "n_forced", - "prev_forced_n", - "prev_forced_t", - "t", - NULL -}; - -static void do_video_stats(OutputStream *ost, int frame_size); -static int64_t getutime(void); -static int64_t getmaxrss(void); - -static int run_as_daemon = 0; static int64_t video_size = 0; static int64_t audio_size = 0; -static int64_t subtitle_size = 0; static int64_t extra_size = 0; static int nb_frames_dup = 0; static int nb_frames_drop = 0; -static int64_t decode_error_stat[2]; -static int current_time; -AVIOContext *progress_avio = NULL; -static uint8_t *subtitle_out; #if HAVE_PTHREADS /* signal to input threads that they should exit; set by the main thread */ static int transcoding_finished; #endif -#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass" +#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass" InputStream **input_streams = NULL; int nb_input_streams = 0; @@ -156,159 +112,9 @@ int nb_output_files = 0; FilterGraph **filtergraphs; int nb_filtergraphs; -#if HAVE_TERMIOS_H - -/* init terminal so that we can grab keys */ -static struct termios oldtty; -static int restore_tty; -#endif - -static void free_input_threads(void); - - -/* sub2video hack: - Convert subtitles to video with alpha to insert them in filter graphs. - This is a temporary solution until libavfilter gets real subtitles support. - */ - -static int sub2video_get_blank_frame(InputStream *ist) +static void term_exit(void) { - int ret; - AVFrame *frame = ist->sub2video.frame; - - av_frame_unref(frame); - ist->sub2video.frame->width = ist->sub2video.w; - ist->sub2video.frame->height = ist->sub2video.h; - ist->sub2video.frame->format = AV_PIX_FMT_RGB32; - if ((ret = av_frame_get_buffer(frame, 32)) < 0) - return ret; - memset(frame->data[0], 0, frame->height * frame->linesize[0]); - return 0; -} - -static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h, - AVSubtitleRect *r) -{ - uint32_t *pal, *dst2; - uint8_t *src, *src2; - int x, y; - - if (r->type != SUBTITLE_BITMAP) { - av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n"); - return; - } - if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) { - av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle overflowing\n"); - return; - } - - dst += r->y * dst_linesize + r->x * 4; - src = r->pict.data[0]; - pal = (uint32_t *)r->pict.data[1]; - for (y = 0; y < r->h; y++) { - dst2 = (uint32_t *)dst; - src2 = src; - for (x = 0; x < r->w; x++) - *(dst2++) = pal[*(src2++)]; - dst += dst_linesize; - src += r->pict.linesize[0]; - } -} - -static void sub2video_push_ref(InputStream *ist, int64_t pts) -{ - AVFrame *frame = ist->sub2video.frame; - int i; - - av_assert1(frame->data[0]); - ist->sub2video.last_pts = frame->pts = pts; - for (i = 0; i < ist->nb_filters; i++) - av_buffersrc_add_frame_flags(ist->filters[i]->filter, frame, - AV_BUFFERSRC_FLAG_KEEP_REF | - AV_BUFFERSRC_FLAG_PUSH); -} - -static void sub2video_update(InputStream *ist, AVSubtitle *sub) -{ - int w = ist->sub2video.w, h = ist->sub2video.h; - AVFrame *frame = ist->sub2video.frame; - int8_t *dst; - int dst_linesize; - int num_rects, i; - int64_t pts, end_pts; - - if (!frame) - return; - if (sub) { - pts = av_rescale_q(sub->pts + sub->start_display_time * 1000, - AV_TIME_BASE_Q, ist->st->time_base); - end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000, - AV_TIME_BASE_Q, ist->st->time_base); - num_rects = sub->num_rects; - } else { - pts = ist->sub2video.end_pts; - end_pts = INT64_MAX; - num_rects = 0; - } - if (sub2video_get_blank_frame(ist) < 0) { - av_log(ist->st->codec, AV_LOG_ERROR, - "Impossible to get a blank canvas.\n"); - return; - } - dst = frame->data [0]; - dst_linesize = frame->linesize[0]; - for (i = 0; i < num_rects; i++) - sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]); - sub2video_push_ref(ist, pts); - ist->sub2video.end_pts = end_pts; -} - -static void sub2video_heartbeat(InputStream *ist, int64_t pts) -{ - InputFile *infile = input_files[ist->file_index]; - int i, j, nb_reqs; - int64_t pts2; - - /* When a frame is read from a file, examine all sub2video streams in - the same file and send the sub2video frame again. Otherwise, decoded - video frames could be accumulating in the filter graph while a filter - (possibly overlay) is desperately waiting for a subtitle frame. */ - for (i = 0; i < infile->nb_streams; i++) { - InputStream *ist2 = input_streams[infile->ist_index + i]; - if (!ist2->sub2video.frame) - continue; - /* subtitles seem to be usually muxed ahead of other streams; - if not, substracting a larger time here is necessary */ - pts2 = av_rescale_q(pts, ist->st->time_base, ist2->st->time_base) - 1; - /* do not send the heartbeat frame if the subtitle is already ahead */ - if (pts2 <= ist2->sub2video.last_pts) - continue; - if (pts2 >= ist2->sub2video.end_pts || !ist2->sub2video.frame->data[0]) - sub2video_update(ist2, NULL); - for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++) - nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter); - if (nb_reqs) - sub2video_push_ref(ist2, pts2); - } -} - -static void sub2video_flush(InputStream *ist) -{ - int i; - - for (i = 0; i < ist->nb_filters; i++) - av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0); -} - -/* end of sub2video hack */ - -void term_exit(void) -{ - av_log(NULL, AV_LOG_QUIET, "%s", ""); -#if HAVE_TERMIOS_H - if(restore_tty) - tcsetattr (0, TCSANOW, &oldtty); -#endif + av_log(NULL, AV_LOG_QUIET, ""); } static volatile int received_sigterm = 0; @@ -320,39 +126,10 @@ sigterm_handler(int sig) received_sigterm = sig; received_nb_signals++; term_exit(); - if(received_nb_signals > 3) - exit_program(123); } -void term_init(void) +static void term_init(void) { -#if HAVE_TERMIOS_H - if(!run_as_daemon){ - struct termios tty; - int istty = 1; -#if HAVE_ISATTY - istty = isatty(0) && isatty(2); -#endif - if (istty && tcgetattr (0, &tty) == 0) { - oldtty = tty; - restore_tty = 1; - - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - - tcsetattr (0, TCSANOW, &tty); - } - signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ - } -#endif - avformat_network_deinit(); - signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ #ifdef SIGXCPU @@ -360,62 +137,6 @@ void term_init(void) #endif } -/* read a key without blocking */ -static int read_key(void) -{ - unsigned char ch; -#if HAVE_TERMIOS_H - int n = 1; - struct timeval tv; - fd_set rfds; - - FD_ZERO(&rfds); - FD_SET(0, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 0; - n = select(1, &rfds, NULL, NULL, &tv); - if (n > 0) { - n = read(0, &ch, 1); - if (n == 1) - return ch; - - return n; - } -#elif HAVE_KBHIT -# if HAVE_PEEKNAMEDPIPE - static int is_pipe; - static HANDLE input_handle; - DWORD dw, nchars; - if(!input_handle){ - input_handle = GetStdHandle(STD_INPUT_HANDLE); - is_pipe = !GetConsoleMode(input_handle, &dw); - } - - if (stdin->_cnt > 0) { - read(0, &ch, 1); - return ch; - } - if (is_pipe) { - /* When running under a GUI, you will end here. */ - if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL)) { - // input pipe may have been closed by the program that ran ffmpeg - return -1; - } - //Read it - if(nchars != 0) { - read(0, &ch, 1); - return ch; - }else{ - return -1; - } - } -# endif - if(kbhit()) - return(getch()); -#endif - return -1; -} - static int decode_interrupt_cb(void *ctx) { return received_nb_signals > 1; @@ -423,15 +144,10 @@ static int decode_interrupt_cb(void *ctx) const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; -static void ffmpeg_cleanup(int ret) +static void avconv_cleanup(int ret) { int i, j; - if (do_benchmark) { - int maxrss = getmaxrss() / 1024; - printf("bench: maxrss=%ikB\n", maxrss); - } - for (i = 0; i < nb_filtergraphs; i++) { avfilter_graph_free(&filtergraphs[i]->graph); for (j = 0; j < filtergraphs[i]->nb_inputs; j++) { @@ -449,8 +165,6 @@ static void ffmpeg_cleanup(int ret) } av_freep(&filtergraphs); - av_freep(&subtitle_out); - /* close files */ for (i = 0; i < nb_output_files; i++) { AVFormatContext *s = output_files[i]->ctx; @@ -473,14 +187,10 @@ static void ffmpeg_cleanup(int ret) av_parser_close(output_streams[i]->parser); av_freep(&output_streams[i]->forced_keyframes); - av_expr_free(output_streams[i]->forced_keyframes_pexpr); av_freep(&output_streams[i]->avfilter); av_freep(&output_streams[i]->logfile_prefix); av_freep(&output_streams[i]); } -#if HAVE_PTHREADS - free_input_threads(); -#endif for (i = 0; i < nb_input_files; i++) { avformat_close_input(&input_files[i]->ctx); av_freep(&input_files[i]); @@ -489,8 +199,6 @@ static void ffmpeg_cleanup(int ret) av_frame_free(&input_streams[i]->decoded_frame); av_frame_free(&input_streams[i]->filter_frame); av_dict_free(&input_streams[i]->opts); - avsubtitle_free(&input_streams[i]->prev_sub.subtitle); - av_frame_free(&input_streams[i]->sub2video.frame); av_freep(&input_streams[i]->filters); av_freep(&input_streams[i]->hwaccel_device); av_freep(&input_streams[i]); @@ -512,8 +220,8 @@ static void ffmpeg_cleanup(int ret) if (received_sigterm) { av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n", (int) received_sigterm); + exit (255); } - term_exit(); } void assert_avoptions(AVDictionary *m) @@ -527,23 +235,74 @@ void assert_avoptions(AVDictionary *m) static void abort_codec_experimental(AVCodec *c, int encoder) { + const char *codec_string = encoder ? "encoder" : "decoder"; + AVCodec *codec; + av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad " + "results.\nAdd '-strict experimental' if you want to use it.\n", + codec_string, c->name); + codec = encoder ? avcodec_find_encoder(c->id) : avcodec_find_decoder(c->id); + if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL)) + av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n", + codec_string, codec->name); exit_program(1); } -static void update_benchmark(const char *fmt, ...) +/* + * Update the requested input sample format based on the output sample format. + * This is currently only used to request float output from decoders which + * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT. + * Ideally this will be removed in the future when decoders do not do format + * conversion and only output in their native format. + */ +static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec, + AVCodecContext *enc) { - if (do_benchmark_all) { - int64_t t = getutime(); - va_list va; - char buf[1024]; + /* if sample formats match or a decoder sample format has already been + requested, just return */ + if (enc->sample_fmt == dec->sample_fmt || + dec->request_sample_fmt > AV_SAMPLE_FMT_NONE) + return; - if (fmt) { - va_start(va, fmt); - vsnprintf(buf, sizeof(buf), fmt, va); - va_end(va); - printf("bench: %8"PRIu64" %s \n", t - current_time, buf); + /* if decoder supports more than one output format */ + if (dec_codec && dec_codec->sample_fmts && + dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE && + dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) { + const enum AVSampleFormat *p; + int min_dec = INT_MAX, min_inc = INT_MAX; + enum AVSampleFormat dec_fmt = AV_SAMPLE_FMT_NONE; + enum AVSampleFormat inc_fmt = AV_SAMPLE_FMT_NONE; + + /* find a matching sample format in the encoder */ + for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) { + if (*p == enc->sample_fmt) { + dec->request_sample_fmt = *p; + return; + } else { + enum AVSampleFormat dfmt = av_get_packed_sample_fmt(*p); + enum AVSampleFormat efmt = av_get_packed_sample_fmt(enc->sample_fmt); + int fmt_diff = 32 * abs(dfmt - efmt); + if (av_sample_fmt_is_planar(*p) != + av_sample_fmt_is_planar(enc->sample_fmt)) + fmt_diff++; + if (dfmt == efmt) { + min_inc = fmt_diff; + inc_fmt = *p; + } else if (dfmt > efmt) { + if (fmt_diff < min_inc) { + min_inc = fmt_diff; + inc_fmt = *p; + } + } else { + if (fmt_diff < min_dec) { + min_dec = fmt_diff; + dec_fmt = *p; + } + } + } } - current_time = t; + + /* if none match, provide the one that matches quality closest */ + dec->request_sample_fmt = min_inc != INT_MAX ? inc_fmt : dec_fmt; } } @@ -553,10 +312,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) AVCodecContext *avctx = ost->st->codec; int ret; - if ((avctx->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) || - (avctx->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0)) - pkt->pts = pkt->dts = AV_NOPTS_VALUE; - /* * Audio encoders may split the packets -- #frames in != #packets out. * But there is no reordering, so we can limit the number of output packets @@ -578,17 +333,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) &new_pkt.data, &new_pkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY); - if(a == 0 && new_pkt.data != pkt->data && new_pkt.destruct) { - uint8_t *t = av_malloc(new_pkt.size + FF_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow - if(t) { - memcpy(t, new_pkt.data, new_pkt.size); - memset(t + new_pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - new_pkt.data = t; - new_pkt.buf = NULL; - a = 1; - } else - a = AVERROR(ENOMEM); - } if (a > 0) { av_free_packet(pkt); new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, @@ -596,7 +340,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) if (!new_pkt.buf) exit_program(1); } else if (a < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to open bitstream filter %s for stream %d with codec %s", + av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s", bsfc->filter->name, pkt->stream_index, avctx->codec ? avctx->codec->name : "copy"); print_error("", a); @@ -609,41 +353,25 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) } if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) && - (avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) && - pkt->dts != AV_NOPTS_VALUE && - ost->last_mux_dts != AV_NOPTS_VALUE) { - int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT); - if (pkt->dts < max) { - int loglevel = max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG; - av_log(s, loglevel, "Non-monotonous DTS in output stream " + ost->last_mux_dts != AV_NOPTS_VALUE && + pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) { + av_log(NULL, AV_LOG_WARNING, "Non-monotonous DTS in output stream " "%d:%d; previous: %"PRId64", current: %"PRId64"; ", ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts); if (exit_on_error) { av_log(NULL, AV_LOG_FATAL, "aborting.\n"); exit_program(1); } - av_log(s, loglevel, "changing to %"PRId64". This may result " + av_log(NULL, AV_LOG_WARNING, "changing to %"PRId64". This may result " "in incorrect timestamps in the output file.\n", - max); - if(pkt->pts >= pkt->dts) - pkt->pts = FFMAX(pkt->pts, max); - pkt->dts = max; - } + ost->last_mux_dts + 1); + pkt->dts = ost->last_mux_dts + 1; + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts = FFMAX(pkt->pts, pkt->dts); } ost->last_mux_dts = pkt->dts; pkt->stream_index = ost->index; - - if (debug_ts) { - av_log(NULL, AV_LOG_INFO, "muxer <- type:%s " - "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n", - av_get_media_type_string(ost->st->codec->codec_type), - av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base), - av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base), - pkt->size - ); - } - ret = av_interleaved_write_frame(s, pkt); if (ret < 0) { print_error("av_interleaved_write_frame()", ret); @@ -651,17 +379,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) } } -static void close_output_stream(OutputStream *ost) -{ - OutputFile *of = output_files[ost->file_index]; - - ost->finished = 1; - if (of->shortest) { - int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, AV_TIME_BASE_Q); - of->recording_time = FFMIN(of->recording_time, end); - } -} - static int check_recording_time(OutputStream *ost) { OutputFile *of = output_files[ost->file_index]; @@ -669,7 +386,7 @@ static int check_recording_time(OutputStream *ost) if (of->recording_time != INT64_MAX && av_compare_ts(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, of->recording_time, AV_TIME_BASE_Q) >= 0) { - close_output_stream(ost); + ost->finished = 1; return 0; } return 1; @@ -686,20 +403,14 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, pkt.data = NULL; pkt.size = 0; - if (!check_recording_time(ost)) - return; - if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0) frame->pts = ost->sync_opts; ost->sync_opts = frame->pts + frame->nb_samples; - av_assert0(pkt.size || !pkt.data); - update_benchmark(NULL); if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) { - av_log(NULL, AV_LOG_FATAL, "Audio encoding failed (avcodec_encode_audio2)\n"); + av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n"); exit_program(1); } - update_benchmark("encode_audio %d.%d", ost->file_index, ost->index); if (got_packet) { if (pkt.pts != AV_NOPTS_VALUE) @@ -709,32 +420,25 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, if (pkt.duration > 0) pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base); - if (debug_ts) { - av_log(NULL, AV_LOG_INFO, "encoder -> type:audio " - "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base)); - } - - audio_size += pkt.size; write_frame(s, &pkt, ost); - av_free_packet(&pkt); + audio_size += pkt.size; } } static void do_subtitle_out(AVFormatContext *s, OutputStream *ost, InputStream *ist, - AVSubtitle *sub) + AVSubtitle *sub, + int64_t pts) { + static uint8_t *subtitle_out = NULL; int subtitle_out_max_size = 1024 * 1024; int subtitle_out_size, nb, i; AVCodecContext *enc; AVPacket pkt; - int64_t pts; - if (sub->pts == AV_NOPTS_VALUE) { + if (pts == AV_NOPTS_VALUE) { av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); if (exit_on_error) exit_program(1); @@ -755,22 +459,16 @@ static void do_subtitle_out(AVFormatContext *s, else nb = 1; - /* shift timestamp to honor -ss and make check_recording_time() work with -t */ - pts = sub->pts; - if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE) - pts -= output_files[ost->file_index]->start_time; for (i = 0; i < nb; i++) { - ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base); + ost->sync_opts = av_rescale_q(pts, ist->st->time_base, enc->time_base); if (!check_recording_time(ost)) return; - sub->pts = pts; + sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); // start_display_time is required to be 0 sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); sub->end_display_time -= sub->start_display_time; sub->start_display_time = 0; - if (i == 1) - sub->num_rects = 0; subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, subtitle_out_max_size, sub); if (subtitle_out_size < 0) { @@ -782,7 +480,6 @@ static void do_subtitle_out(AVFormatContext *s, pkt.data = subtitle_out; pkt.size = subtitle_out_size; pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base); - pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->st->time_base); if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { /* XXX: the pts correction is handled here. Maybe handling it in the codec would be better */ @@ -791,109 +488,47 @@ static void do_subtitle_out(AVFormatContext *s, else pkt.pts += 90 * sub->end_display_time; } - subtitle_size += pkt.size; write_frame(s, &pkt, ost); } } static void do_video_out(AVFormatContext *s, OutputStream *ost, - AVFrame *in_picture) + AVFrame *in_picture, + int *frame_size) { int ret, format_video_sync; AVPacket pkt; AVCodecContext *enc = ost->st->codec; - int nb_frames, i; - double sync_ipts, delta; - double duration = 0; - int frame_size = 0; - InputStream *ist = NULL; - if (ost->source_index >= 0) - ist = input_streams[ost->source_index]; - - if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num) - duration = 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base)); - - sync_ipts = in_picture->pts; - delta = sync_ipts - ost->sync_opts + duration; - - /* by default, we output a single frame */ - nb_frames = 1; + *frame_size = 0; format_video_sync = video_sync_method; - if (format_video_sync == VSYNC_AUTO) { - if(!strcmp(s->oformat->name, "avi")) { - format_video_sync = VSYNC_VFR; - } else - format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR; - if ( ist - && format_video_sync == VSYNC_CFR - && input_files[ist->file_index]->ctx->nb_streams == 1 - && input_files[ist->file_index]->input_ts_offset == 0) { - format_video_sync = VSYNC_VSCFR; - } - if (format_video_sync == VSYNC_CFR && copy_ts) { - format_video_sync = VSYNC_VSCFR; - } - } - - switch (format_video_sync) { - case VSYNC_VSCFR: - if (ost->frame_number == 0 && delta - duration >= 0.5) { - av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta - duration)); - delta = duration; - ost->sync_opts = lrint(sync_ipts); - } - case VSYNC_CFR: - // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c - if (delta < -1.1) - nb_frames = 0; - else if (delta > 1.1) - nb_frames = lrintf(delta); - break; - case VSYNC_VFR: - if (delta <= -0.6) - nb_frames = 0; - else if (delta > 0.6) - ost->sync_opts = lrint(sync_ipts); - break; - case VSYNC_DROP: - case VSYNC_PASSTHROUGH: - ost->sync_opts = lrint(sync_ipts); - break; - default: - av_assert0(0); - } - - nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number); - if (nb_frames == 0) { + if (format_video_sync == VSYNC_AUTO) + format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : + (s->oformat->flags & AVFMT_VARIABLE_FPS) ? VSYNC_VFR : VSYNC_CFR; + if (format_video_sync != VSYNC_PASSTHROUGH && + ost->frame_number && + in_picture->pts != AV_NOPTS_VALUE && + in_picture->pts < ost->sync_opts) { nb_frames_drop++; av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n"); return; - } else if (nb_frames > 1) { - if (nb_frames > dts_error_threshold * 30) { - av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1); - nb_frames_drop++; - return; - } - nb_frames_dup += nb_frames - 1; - av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1); } - /* duplicates frame if needed */ - for (i = 0; i < nb_frames; i++) { + if (in_picture->pts == AV_NOPTS_VALUE) + in_picture->pts = ost->sync_opts; + ost->sync_opts = in_picture->pts; + + + if (!ost->frame_number) + ost->first_pts = in_picture->pts; + av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; - in_picture->pts = ost->sync_opts; - -#if 1 - if (!check_recording_time(ost)) -#else if (ost->frame_number >= ost->max_frames) -#endif return; if (s->oformat->flags & AVFMT_RAWPICTURE && @@ -903,99 +538,42 @@ static void do_video_out(AVFormatContext *s, method. */ enc->coded_frame->interlaced_frame = in_picture->interlaced_frame; enc->coded_frame->top_field_first = in_picture->top_field_first; - if (enc->coded_frame->interlaced_frame) - enc->field_order = enc->coded_frame->top_field_first ? AV_FIELD_TB:AV_FIELD_BT; - else - enc->field_order = AV_FIELD_PROGRESSIVE; pkt.data = (uint8_t *)in_picture; pkt.size = sizeof(AVPicture); pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base); pkt.flags |= AV_PKT_FLAG_KEY; - video_size += pkt.size; write_frame(s, &pkt, ost); } else { - int got_packet, forced_keyframe = 0; - double pts_time; + int got_packet; if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) && ost->top_field_first >= 0) in_picture->top_field_first = !!ost->top_field_first; - if (in_picture->interlaced_frame) { - if (enc->codec->id == AV_CODEC_ID_MJPEG) - enc->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB; - else - enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT; - } else - enc->field_order = AV_FIELD_PROGRESSIVE; - in_picture->quality = ost->st->codec->global_quality; if (!enc->me_threshold) in_picture->pict_type = 0; - - pts_time = in_picture->pts != AV_NOPTS_VALUE ? - in_picture->pts * av_q2d(enc->time_base) : NAN; if (ost->forced_kf_index < ost->forced_kf_count && in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) { - ost->forced_kf_index++; - forced_keyframe = 1; - } else if (ost->forced_keyframes_pexpr) { - double res; - ost->forced_keyframes_expr_const_values[FKF_T] = pts_time; - res = av_expr_eval(ost->forced_keyframes_pexpr, - ost->forced_keyframes_expr_const_values, NULL); - av_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", - ost->forced_keyframes_expr_const_values[FKF_N], - ost->forced_keyframes_expr_const_values[FKF_N_FORCED], - ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N], - ost->forced_keyframes_expr_const_values[FKF_T], - ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T], - res); - if (res) { - forced_keyframe = 1; - ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] = - ost->forced_keyframes_expr_const_values[FKF_N]; - ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] = - ost->forced_keyframes_expr_const_values[FKF_T]; - ost->forced_keyframes_expr_const_values[FKF_N_FORCED] += 1; - } - - ost->forced_keyframes_expr_const_values[FKF_N] += 1; - } - if (forced_keyframe) { in_picture->pict_type = AV_PICTURE_TYPE_I; - av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time); + ost->forced_kf_index++; } - - update_benchmark(NULL); ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet); - update_benchmark("encode_video %d.%d", ost->file_index, ost->index); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n"); exit_program(1); } if (got_packet) { - if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY)) - pkt.pts = ost->sync_opts; - if (pkt.pts != AV_NOPTS_VALUE) pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); if (pkt.dts != AV_NOPTS_VALUE) pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); - if (debug_ts) { - av_log(NULL, AV_LOG_INFO, "encoder -> type:video " - "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base)); - } - - frame_size = pkt.size; - video_size += pkt.size; write_frame(s, &pkt, ost); - av_free_packet(&pkt); + *frame_size = pkt.size; + video_size += pkt.size; /* if two pass, output log */ if (ost->logfile && enc->stats_out) { @@ -1010,10 +588,6 @@ static void do_video_out(AVFormatContext *s, * flush, we need to limit them here, before they go into encoder. */ ost->frame_number++; - - if (vstats_filename && frame_size) - do_video_stats(ost, frame_size); - } } static double psnr(double d) @@ -1038,14 +612,14 @@ static void do_video_stats(OutputStream *ost, int frame_size) enc = ost->st->codec; if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { - frame_number = ost->st->nb_frames; + frame_number = ost->frame_number; fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA); if (enc->flags&CODEC_FLAG_PSNR) fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0))); fprintf(vstats_file,"f_size= %6d ", frame_size); /* compute pts value */ - ti1 = ost->st->pts.val * av_q2d(enc->time_base); + ti1 = ost->sync_opts * av_q2d(enc->time_base); if (ti1 < 0.01) ti1 = 0.01; @@ -1057,105 +631,135 @@ static void do_video_stats(OutputStream *ost, int frame_size) } } -/** - * Get and encode new output from any of the filtergraphs, without causing - * activity. - * - * @return 0 for success, <0 for severe errors +/* + * Read one frame for lavfi output for ost and encode it. */ -static int reap_filters(void) +static int poll_filter(OutputStream *ost) { + OutputFile *of = output_files[ost->file_index]; AVFrame *filtered_frame = NULL; - int i; - int64_t frame_pts; + int frame_size, ret; - /* Reap all buffers present in the buffer sinks */ - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; - OutputFile *of = output_files[ost->file_index]; - int ret = 0; - - if (!ost->filter) - continue; - - if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) { - return AVERROR(ENOMEM); - } - filtered_frame = ost->filtered_frame; - - while (1) { - ret = av_buffersink_get_frame_flags(ost->filter->filter, filtered_frame, - AV_BUFFERSINK_FLAG_NO_REQUEST); - if (ret < 0) { - if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { - av_log(NULL, AV_LOG_WARNING, - "Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret)); - } - break; - } - frame_pts = AV_NOPTS_VALUE; - if (filtered_frame->pts != AV_NOPTS_VALUE) { - int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; - filtered_frame->pts = frame_pts = av_rescale_q(filtered_frame->pts, - ost->filter->filter->inputs[0]->time_base, - ost->st->codec->time_base) - - av_rescale_q(start_time, - AV_TIME_BASE_Q, - ost->st->codec->time_base); - } - //if (ost->source_index >= 0) - // *filtered_frame= *input_streams[ost->source_index]->decoded_frame; //for me_threshold - - - switch (ost->filter->filter->inputs[0]->type) { - case AVMEDIA_TYPE_VIDEO: - filtered_frame->pts = frame_pts; - if (!ost->frame_aspect_ratio.num) - ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; - - do_video_out(of->ctx, ost, filtered_frame); - break; - case AVMEDIA_TYPE_AUDIO: - filtered_frame->pts = frame_pts; - if (!(ost->st->codec->codec->capabilities & CODEC_CAP_PARAM_CHANGE) && - ost->st->codec->channels != av_frame_get_channels(filtered_frame)) { - av_log(NULL, AV_LOG_ERROR, - "Audio filter graph output is not normalized and encoder does not support parameter changes\n"); - break; - } - do_audio_out(of->ctx, ost, filtered_frame); - break; - default: - // TODO support subtitle filters - av_assert0(0); - } - - av_frame_unref(filtered_frame); - } + if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) { + return AVERROR(ENOMEM); } + filtered_frame = ost->filtered_frame; + + if (ost->enc->type == AVMEDIA_TYPE_AUDIO && + !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) + ret = av_buffersink_get_samples(ost->filter->filter, filtered_frame, + ost->st->codec->frame_size); + else + ret = av_buffersink_get_frame(ost->filter->filter, filtered_frame); + + if (ret < 0) + return ret; + + if (filtered_frame->pts != AV_NOPTS_VALUE) { + int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; + filtered_frame->pts = av_rescale_q(filtered_frame->pts, + ost->filter->filter->inputs[0]->time_base, + ost->st->codec->time_base) - + av_rescale_q(start_time, + AV_TIME_BASE_Q, + ost->st->codec->time_base); + } + + switch (ost->filter->filter->inputs[0]->type) { + case AVMEDIA_TYPE_VIDEO: + if (!ost->frame_aspect_ratio) + ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; + + do_video_out(of->ctx, ost, filtered_frame, &frame_size); + if (vstats_filename && frame_size) + do_video_stats(ost, frame_size); + break; + case AVMEDIA_TYPE_AUDIO: + do_audio_out(of->ctx, ost, filtered_frame); + break; + default: + // TODO support subtitle filters + av_assert0(0); + } + + av_frame_unref(filtered_frame); return 0; } -static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time) +/* + * Read as many frames from possible from lavfi and encode them. + * + * Always read from the active stream with the lowest timestamp. If no frames + * are available for it then return EAGAIN and wait for more input. This way we + * can use lavfi sources that generate unlimited amount of frames without memory + * usage exploding. + */ +static int poll_filters(void) +{ + int i, j, ret = 0; + + while (ret >= 0 && !received_sigterm) { + OutputStream *ost = NULL; + int64_t min_pts = INT64_MAX; + + /* choose output stream with the lowest timestamp */ + for (i = 0; i < nb_output_streams; i++) { + int64_t pts = output_streams[i]->sync_opts; + + if (!output_streams[i]->filter || output_streams[i]->finished) + continue; + + pts = av_rescale_q(pts, output_streams[i]->st->codec->time_base, + AV_TIME_BASE_Q); + if (pts < min_pts) { + min_pts = pts; + ost = output_streams[i]; + } + } + + if (!ost) + break; + + ret = poll_filter(ost); + + if (ret == AVERROR_EOF) { + OutputFile *of = output_files[ost->file_index]; + + ost->finished = 1; + + if (of->shortest) { + for (j = 0; j < of->ctx->nb_streams; j++) + output_streams[of->ost_index + j]->finished = 1; + } + + ret = 0; + } else if (ret == AVERROR(EAGAIN)) + return 0; + } + + return ret; +} + +static void print_report(int is_last_report, int64_t timer_start) { char buf[1024]; - AVBPrint buf_script; OutputStream *ost; AVFormatContext *oc; int64_t total_size; AVCodecContext *enc; int frame_number, vid, i; - double bitrate; - int64_t pts = INT64_MIN; + double bitrate, ti1, pts; static int64_t last_time = -1; static int qp_histogram[52]; - int hours, mins, secs, us; - if (!print_stats && !is_last_report && !progress_avio) + if (!print_stats && !is_last_report) return; if (!is_last_report) { + int64_t cur_time; + /* display the report every 0.5 seconds */ + cur_time = av_gettime(); if (last_time == -1) { last_time = cur_time; return; @@ -1171,10 +775,17 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti total_size = avio_size(oc->pb); if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too total_size = avio_tell(oc->pb); + if (total_size < 0) { + char errbuf[128]; + av_strerror(total_size, errbuf, sizeof(errbuf)); + av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, " + "avio_tell() failed: %s\n", errbuf); + total_size = 0; + } buf[0] = '\0'; + ti1 = 1e10; vid = 0; - av_bprint_init(&buf_script, 0, 1); for (i = 0; i < nb_output_streams; i++) { float q = -1; ost = output_streams[i]; @@ -1183,20 +794,13 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti q = enc->coded_frame->quality / (float)FF_QP2LAMBDA; if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q); - av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n", - ost->file_index, ost->index, q); } if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { - float fps, t = (cur_time-timer_start) / 1000000.0; + float t = (av_gettime() - timer_start) / 1000000.0; frame_number = ost->frame_number; - fps = t > 1 ? frame_number / t : 0; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ", - frame_number, fps < 9.95, fps, q); - av_bprintf(&buf_script, "frame=%d\n", frame_number); - av_bprintf(&buf_script, "fps=%.1f\n", fps); - av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n", - ost->file_index, ost->index, q); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ", + frame_number, (t > 1) ? (int)(frame_number / t + 0.5) : 0, q); if (is_last_report) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L"); if (qp_hist) { @@ -1207,11 +811,10 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti for (j = 0; j < 32; j++) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1))); } - if ((enc->flags&CODEC_FLAG_PSNR) && (enc->coded_frame || is_last_report)) { + if (enc->flags&CODEC_FLAG_PSNR) { int j; double error, error_sum = 0; double scale, scale_sum = 0; - double p; char type[3] = { 'Y','U','V' }; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR="); for (j = 0; j < 3; j++) { @@ -1226,91 +829,43 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti scale /= 4; error_sum += error; scale_sum += scale; - p = psnr(error / scale); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], p); - av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n", - ost->file_index, ost->index, type[j] | 32, p); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error / scale)); } - p = psnr(error_sum / scale_sum); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum)); - av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n", - ost->file_index, ost->index, p); } vid = 1; } /* compute min output value */ - if ((is_last_report || !ost->finished) && ost->st->pts.val != AV_NOPTS_VALUE) - pts = FFMAX(pts, av_rescale_q(ost->st->pts.val, - ost->st->time_base, AV_TIME_BASE_Q)); + pts = (double)ost->st->pts.val * av_q2d(ost->st->time_base); + if ((pts < ti1) && (pts > 0)) + ti1 = pts; } + if (ti1 < 0.01) + ti1 = 0.01; - secs = pts / AV_TIME_BASE; - us = pts % AV_TIME_BASE; - mins = secs / 60; - secs %= 60; - hours = mins / 60; - mins %= 60; + bitrate = (double)(total_size * 8) / ti1 / 1000.0; - bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1; - - if (total_size < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "size=N/A time="); - else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "size=%8.0fkB time=", total_size / 1024.0); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%02d:%02d:%02d.%02d ", hours, mins, secs, - (100 * us) / AV_TIME_BASE); - if (bitrate < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "bitrate=N/A"); - else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "bitrate=%6.1fkbits/s", bitrate); - if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n"); - else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size); - av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts); - av_bprintf(&buf_script, "out_time=%02d:%02d:%02d.%06d\n", - hours, mins, secs, us); + "size=%8.0fkB time=%0.2f bitrate=%6.1fkbits/s", + (double)total_size / 1024, ti1, bitrate); if (nb_frames_dup || nb_frames_drop) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d", nb_frames_dup, nb_frames_drop); - av_bprintf(&buf_script, "dup_frames=%d\n", nb_frames_dup); - av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop); - if (print_stats || is_last_report) { - if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) { - fprintf(stderr, "%s \r", buf); - } else - av_log(NULL, AV_LOG_INFO, "%s \r", buf); + av_log(NULL, AV_LOG_INFO, "%s \r", buf); fflush(stderr); - } - - if (progress_avio) { - av_bprintf(&buf_script, "progress=%s\n", - is_last_report ? "end" : "continue"); - avio_write(progress_avio, buf_script.str, - FFMIN(buf_script.len, buf_script.size - 1)); - avio_flush(progress_avio); - av_bprint_finalize(&buf_script, NULL); - if (is_last_report) { - avio_close(progress_avio); - progress_avio = NULL; - } - } if (is_last_report) { - int64_t raw= audio_size + video_size + subtitle_size + extra_size; + int64_t raw= audio_size + video_size + extra_size; av_log(NULL, AV_LOG_INFO, "\n"); - av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB subtitle:%1.0f global headers:%1.0fkB muxing overhead %f%%\n", + av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n", video_size / 1024.0, audio_size / 1024.0, - subtitle_size / 1024.0, extra_size / 1024.0, 100.0 * (total_size - raw) / raw ); - if(video_size + audio_size + subtitle_size + extra_size == 0){ - av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)\n"); - } } } @@ -1359,14 +914,12 @@ static void flush_encoders(void) pkt.data = NULL; pkt.size = 0; - update_benchmark(NULL); ret = encode(enc, &pkt, NULL, &got_packet); - update_benchmark("flush %s %d.%d", desc, ost->file_index, ost->index); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc); exit_program(1); } - *size += pkt.size; + *size += ret; if (ost->logfile && enc->stats_out) { fprintf(ost->logfile, "%s", enc->stats_out); } @@ -1381,9 +934,6 @@ static void flush_encoders(void) if (pkt.duration > 0) pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base); write_frame(os, &pkt, ost); - if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) { - do_video_stats(ost, pkt.size); - } } if (stop_encoding) @@ -1403,7 +953,7 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost) if (ost->source_index != ist_index) return 0; - if (of->start_time != AV_NOPTS_VALUE && ist->pts < of->start_time) + if (of->start_time != AV_NOPTS_VALUE && ist->last_dts < of->start_time) return 0; return 1; @@ -1415,8 +965,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p InputFile *f = input_files [ist->file_index]; int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base); - int64_t ist_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base); - AVPicture pict; AVPacket opkt; av_init_packet(&opkt); @@ -1425,19 +973,9 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p !ost->copy_initial_nonkeyframes) return; - if (pkt->pts == AV_NOPTS_VALUE) { - if (!ost->frame_number && ist->pts < start_time && - !ost->copy_prior_start) - return; - } else { - if (!ost->frame_number && pkt->pts < ist_tb_start_time && - !ost->copy_prior_start) - return; - } - if (of->recording_time != INT64_MAX && - ist->pts >= of->recording_time + start_time) { - close_output_stream(ost); + ist->last_dts >= of->recording_time + start_time) { + ost->finished = 1; return; } @@ -1445,8 +983,8 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p start_time = f->ctx->start_time; if (f->start_time != AV_NOPTS_VALUE) start_time += f->start_time; - if (ist->pts >= f->recording_time + start_time) { - close_output_stream(ost); + if (ist->last_dts >= f->recording_time + start_time) { + ost->finished = 1; return; } } @@ -1457,8 +995,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { video_size += pkt->size; ost->sync_opts++; - } else if (ost->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - subtitle_size += pkt->size; } if (pkt->pts != AV_NOPTS_VALUE) @@ -1467,20 +1003,11 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p opkt.pts = AV_NOPTS_VALUE; if (pkt->dts == AV_NOPTS_VALUE) - opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->st->time_base); + opkt.dts = av_rescale_q(ist->last_dts, AV_TIME_BASE_Q, ost->st->time_base); else opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); opkt.dts -= ost_tb_start_time; - if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) { - int duration = av_get_audio_frame_duration(ist->st->codec, pkt->size); - if(!duration) - duration = ist->st->codec->frame_size; - opkt.dts = opkt.pts = av_rescale_delta(ist->st->time_base, pkt->dts, - (AVRational){1, ist->st->codec->sample_rate}, duration, &ist->filter_in_rescale_delta_last, - ost->st->time_base) - ost_tb_start_time; - } - opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); opkt.flags = pkt->flags; @@ -1502,15 +1029,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p opkt.data = pkt->data; opkt.size = pkt->size; } - av_copy_packet_side_data(&opkt, pkt); - - if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) { - /* store AVPicture in AVPacket, as expected by the output format */ - avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height); - opkt.data = (uint8_t *)&pict; - opkt.size = sizeof(AVPicture); - opkt.flags |= AV_PKT_FLAG_KEY; - } write_frame(of->ctx, &opkt, ost); ost->st->codec->frame_number++; @@ -1523,8 +1041,6 @@ int guess_input_channel_layout(InputStream *ist) if (!dec->channel_layout) { char layout_name[256]; - if (dec->channels > ist->guess_layout_max) - return 0; dec->channel_layout = av_get_default_channel_layout(dec->channels); if (!dec->channel_layout) return 0; @@ -1541,7 +1057,6 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) AVFrame *decoded_frame, *f; AVCodecContext *avctx = ist->st->codec; int i, ret, err = 0, resample_changed; - AVRational decoded_frame_tb; if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) return AVERROR(ENOMEM); @@ -1549,38 +1064,23 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) return AVERROR(ENOMEM); decoded_frame = ist->decoded_frame; - update_benchmark(NULL); ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt); - update_benchmark("decode_audio %d.%d", ist->file_index, ist->st->index); - - if (ret >= 0 && avctx->sample_rate <= 0) { - av_log(avctx, AV_LOG_ERROR, "Sample rate %d invalid\n", avctx->sample_rate); - ret = AVERROR_INVALIDDATA; - } - - if (*got_output || ret<0 || pkt->size) - decode_error_stat[ret<0] ++; - if (!*got_output || ret < 0) { if (!pkt->size) { for (i = 0; i < ist->nb_filters; i++) -#if 1 - av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0); -#else av_buffersrc_add_frame(ist->filters[i]->filter, NULL); -#endif } return ret; } -#if 1 - /* increment next_dts to use for the case where the input stream does not - have timestamps or there are multiple frames in the packet */ - ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) / - avctx->sample_rate; - ist->next_dts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) / - avctx->sample_rate; -#endif + /* if the decoder provides a pts, use it instead of the last packet pts. + the decoder could be delaying output by a packet or more. */ + if (decoded_frame->pts != AV_NOPTS_VALUE) + ist->next_dts = decoded_frame->pts; + else if (pkt->pts != AV_NOPTS_VALUE) { + decoded_frame->pts = pkt->pts; + pkt->pts = AV_NOPTS_VALUE; + } resample_changed = ist->resample_sample_fmt != decoded_frame->format || ist->resample_channels != avctx->channels || @@ -1616,44 +1116,17 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) ist->resample_channels = avctx->channels; for (i = 0; i < nb_filtergraphs; i++) - if (ist_in_filtergraph(filtergraphs[i], ist)) { - FilterGraph *fg = filtergraphs[i]; - int j; - if (configure_filtergraph(fg) < 0) { - av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); - } - for (j = 0; j < fg->nb_outputs; j++) { - OutputStream *ost = fg->outputs[j]->ost; - if (ost->enc->type == AVMEDIA_TYPE_AUDIO && - !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) - av_buffersink_set_frame_size(ost->filter->filter, - ost->st->codec->frame_size); - } + if (ist_in_filtergraph(filtergraphs[i], ist) && + configure_filtergraph(filtergraphs[i]) < 0) { + av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); + exit_program(1); } } - /* if the decoder provides a pts, use it instead of the last packet pts. - the decoder could be delaying output by a packet or more. */ - if (decoded_frame->pts != AV_NOPTS_VALUE) { - ist->dts = ist->next_dts = ist->pts = ist->next_pts = av_rescale_q(decoded_frame->pts, avctx->time_base, AV_TIME_BASE_Q); - decoded_frame_tb = avctx->time_base; - } else if (decoded_frame->pkt_pts != AV_NOPTS_VALUE) { - decoded_frame->pts = decoded_frame->pkt_pts; - pkt->pts = AV_NOPTS_VALUE; - decoded_frame_tb = ist->st->time_base; - } else if (pkt->pts != AV_NOPTS_VALUE) { - decoded_frame->pts = pkt->pts; - pkt->pts = AV_NOPTS_VALUE; - decoded_frame_tb = ist->st->time_base; - }else { - decoded_frame->pts = ist->dts; - decoded_frame_tb = AV_TIME_BASE_Q; - } if (decoded_frame->pts != AV_NOPTS_VALUE) - decoded_frame->pts = av_rescale_delta(decoded_frame_tb, decoded_frame->pts, - (AVRational){1, ist->st->codec->sample_rate}, decoded_frame->nb_samples, &ist->filter_in_rescale_delta_last, - (AVRational){1, ist->st->codec->sample_rate}); + decoded_frame->pts = av_rescale_q(decoded_frame->pts, + ist->st->time_base, + (AVRational){1, ist->st->codec->sample_rate}); for (i = 0; i < ist->nb_filters; i++) { if (i < ist->nb_filters - 1) { f = ist->filter_frame; @@ -1662,14 +1135,11 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) break; } else f = decoded_frame; - err = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f, - AV_BUFFERSRC_FLAG_PUSH); - if (err == AVERROR_EOF) - err = 0; /* ignore */ + + err = av_buffersrc_add_frame(ist->filters[i]->filter, f); if (err < 0) break; } - decoded_frame->pts = AV_NOPTS_VALUE; av_frame_unref(ist->filter_frame); av_frame_unref(decoded_frame); @@ -1680,39 +1150,23 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) { AVFrame *decoded_frame, *f; int i, ret = 0, err = 0, resample_changed; - int64_t best_effort_timestamp; - AVRational *frame_sample_aspect; if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) return AVERROR(ENOMEM); if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc())) return AVERROR(ENOMEM); decoded_frame = ist->decoded_frame; - pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base); - update_benchmark(NULL); ret = avcodec_decode_video2(ist->st->codec, decoded_frame, got_output, pkt); - update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index); - - if (*got_output || ret<0 || pkt->size) - decode_error_stat[ret<0] ++; - if (!*got_output || ret < 0) { if (!pkt->size) { for (i = 0; i < ist->nb_filters; i++) -#if 1 - av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0); -#else av_buffersrc_add_frame(ist->filters[i]->filter, NULL); -#endif } return ret; } - if(ist->top_field_first>=0) - decoded_frame->top_field_first = ist->top_field_first; - if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame); if (err < 0) @@ -1720,20 +1174,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) } ist->hwaccel_retrieved_pix_fmt = decoded_frame->format; - best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame); - if(best_effort_timestamp != AV_NOPTS_VALUE) - ist->next_pts = ist->pts = av_rescale_q(decoded_frame->pts = best_effort_timestamp, ist->st->time_base, AV_TIME_BASE_Q); - - if (debug_ts) { - av_log(NULL, AV_LOG_INFO, "decoder -> ist_index:%d type:video " - "frame_pts:%s frame_pts_time:%s best_effort_ts:%"PRId64" best_effort_ts_time:%s keyframe:%d frame_type:%d \n", - ist->st->index, av_ts2str(decoded_frame->pts), - av_ts2timestr(decoded_frame->pts, &ist->st->time_base), - best_effort_timestamp, - av_ts2timestr(best_effort_timestamp, &ist->st->time_base), - decoded_frame->key_frame, decoded_frame->pict_type); - } - + decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts, + decoded_frame->pkt_dts); pkt->size = 0; if (ist->st->sample_aspect_ratio.num) @@ -1749,24 +1191,23 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) ist->resample_width, ist->resample_height, av_get_pix_fmt_name(ist->resample_pix_fmt), decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format)); + ret = poll_filters(); + if (ret < 0 && (ret != AVERROR_EOF && ret != AVERROR(EAGAIN))) + av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n"); + ist->resample_width = decoded_frame->width; ist->resample_height = decoded_frame->height; ist->resample_pix_fmt = decoded_frame->format; - for (i = 0; i < nb_filtergraphs; i++) { - if (ist_in_filtergraph(filtergraphs[i], ist) && ist->reinit_filters && + for (i = 0; i < nb_filtergraphs; i++) + if (ist_in_filtergraph(filtergraphs[i], ist) && configure_filtergraph(filtergraphs[i]) < 0) { av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); exit_program(1); } - } } - frame_sample_aspect= av_opt_ptr(avcodec_get_frame_class(), decoded_frame, "sample_aspect_ratio"); for (i = 0; i < ist->nb_filters; i++) { - if (!frame_sample_aspect->num) - *frame_sample_aspect = ist->st->sample_aspect_ratio; - if (i < ist->nb_filters - 1) { f = ist->filter_frame; err = av_frame_ref(f, decoded_frame); @@ -1774,14 +1215,10 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) break; } else f = decoded_frame; - ret = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f, AV_BUFFERSRC_FLAG_PUSH); - if (ret == AVERROR_EOF) { - ret = 0; /* ignore */ - } else if (ret < 0) { - av_log(NULL, AV_LOG_FATAL, - "Failed to inject frame into filter network: %s\n", av_err2str(ret)); - exit_program(1); - } + + err = av_buffersrc_add_frame(ist->filters[i]->filter, f); + if (err < 0) + break; } fail: @@ -1795,54 +1232,20 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) AVSubtitle subtitle; int i, ret = avcodec_decode_subtitle2(ist->st->codec, &subtitle, got_output, pkt); - - if (*got_output || ret<0 || pkt->size) - decode_error_stat[ret<0] ++; - - if (ret < 0 || !*got_output) { - if (!pkt->size) - sub2video_flush(ist); + if (ret < 0) return ret; - } - - if (ist->fix_sub_duration) { - int end = 1; - if (ist->prev_sub.got_output) { - end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts, - 1000, AV_TIME_BASE); - if (end < ist->prev_sub.subtitle.end_display_time) { - av_log(ist->st->codec, AV_LOG_DEBUG, - "Subtitle duration reduced from %d to %d%s\n", - ist->prev_sub.subtitle.end_display_time, end, - end <= 0 ? ", dropping it" : ""); - ist->prev_sub.subtitle.end_display_time = end; - } - } - FFSWAP(int, *got_output, ist->prev_sub.got_output); - FFSWAP(int, ret, ist->prev_sub.ret); - FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle); - if (end <= 0) - goto out; - } - if (!*got_output) return ret; - sub2video_update(ist, &subtitle); - - if (!subtitle.num_rects) - goto out; - for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; if (!check_output_constraints(ist, ost) || !ost->encoding_needed) continue; - do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle); + do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle, pkt->pts); } -out: avsubtitle_free(&subtitle); return ret; } @@ -1850,24 +1253,12 @@ out: /* pkt = NULL means EOF (needed to flush decoder buffers) */ static int output_packet(InputStream *ist, const AVPacket *pkt) { - int ret = 0, i; - int got_output = 0; - + int i; + int got_output; AVPacket avpkt; - if (!ist->saw_first_ts) { - ist->dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; - ist->pts = 0; - if (pkt != NULL && pkt->pts != AV_NOPTS_VALUE && !ist->decoding_needed) { - ist->dts += av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q); - ist->pts = ist->dts; //unused but better to set it to a value thats not totally wrong - } - ist->saw_first_ts = 1; - } if (ist->next_dts == AV_NOPTS_VALUE) - ist->next_dts = ist->dts; - if (ist->next_pts == AV_NOPTS_VALUE) - ist->next_pts = ist->pts; + ist->next_dts = ist->last_dts; if (pkt == NULL) { /* EOF handling */ @@ -1879,19 +1270,15 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) avpkt = *pkt; } - if (pkt->dts != AV_NOPTS_VALUE) { - ist->next_dts = ist->dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); - if (ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed) - ist->next_pts = ist->pts = ist->dts; - } + if (pkt->dts != AV_NOPTS_VALUE) + ist->next_dts = ist->last_dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); // while we have more to decode or while the decoder did output something on EOF while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) { - int duration; + int ret = 0; handle_eof: - ist->pts = ist->next_pts; - ist->dts = ist->next_dts; + ist->last_dts = ist->next_dts; if (avpkt.size && avpkt.size != pkt->size) { av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING, @@ -1905,23 +1292,16 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) break; case AVMEDIA_TYPE_VIDEO: ret = decode_video (ist, &avpkt, &got_output); - if (avpkt.duration) { - duration = av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q); - } else if(ist->st->codec->time_base.num != 0 && ist->st->codec->time_base.den != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; - duration = ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; - } else - duration = 0; - - if(ist->dts != AV_NOPTS_VALUE && duration) { - ist->next_dts += duration; - }else - ist->next_dts = AV_NOPTS_VALUE; - - if (got_output) - ist->next_pts += duration; //FIXME the duration is not correct in some cases + if (avpkt.duration) + ist->next_dts += av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q); + else if (ist->st->avg_frame_rate.num) + ist->next_dts += av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), + AV_TIME_BASE_Q); + else if (ist->st->codec->time_base.num != 0) { + int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : + ist->st->codec->ticks_per_frame; + ist->next_dts += av_rescale_q(ticks, ist->st->codec->time_base, AV_TIME_BASE_Q); + } break; case AVMEDIA_TYPE_SUBTITLE: ret = transcode_subtitles(ist, &avpkt, &got_output); @@ -1932,14 +1312,8 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) if (ret < 0) return ret; - - avpkt.dts= - avpkt.pts= AV_NOPTS_VALUE; - // touch data and size only if not EOF if (pkt) { - if(ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO) - ret = avpkt.size; avpkt.data += ret; avpkt.size -= ret; } @@ -1950,30 +1324,21 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) /* handle stream copy */ if (!ist->decoding_needed) { - ist->dts = ist->next_dts; + ist->last_dts = ist->next_dts; switch (ist->st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / ist->st->codec->sample_rate; break; case AVMEDIA_TYPE_VIDEO: - if (ist->framerate.num) { - // TODO: Remove work-around for c99-to-c89 issue 7 - AVRational time_base_q = AV_TIME_BASE_Q; - int64_t next_dts = av_rescale_q(ist->next_dts, time_base_q, av_inv_q(ist->framerate)); - ist->next_dts = av_rescale_q(next_dts + 1, av_inv_q(ist->framerate), time_base_q); - } else if (pkt->duration) { - ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); - } else if(ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame; + if (ist->st->codec->time_base.num != 0) { + int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame; ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; } break; } - ist->pts = ist->dts; - ist->next_pts = ist->next_dts; } for (i = 0; pkt && i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; @@ -2063,17 +1428,26 @@ static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags) static int init_input_stream(int ist_index, char *error, int error_len) { - int ret; + int i, ret; InputStream *ist = input_streams[ist_index]; - if (ist->decoding_needed) { AVCodec *codec = ist->dec; if (!codec) { - snprintf(error, error_len, "Decoder (codec %s) not found for input stream #%d:%d", - avcodec_get_name(ist->st->codec->codec_id), ist->file_index, ist->st->index); + snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d", + ist->st->codec->codec_id, ist->file_index, ist->st->index); return AVERROR(EINVAL); } + /* update requested sample format for the decoder based on the + corresponding encoder sample format */ + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = output_streams[i]; + if (ost->source_index == ist_index) { + update_sample_fmt(ist->st->codec, codec, ost->st->codec); + break; + } + } + ist->st->codec->opaque = ist; ist->st->codec->get_format = get_format; ist->st->codec->get_buffer2 = get_buffer; @@ -2099,8 +1473,9 @@ static int init_input_stream(int ist_index, char *error, int error_len) assert_avoptions(ist->opts); } - ist->next_pts = AV_NOPTS_VALUE; + ist->last_dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; ist->next_dts = AV_NOPTS_VALUE; + init_pts_correction(&ist->pts_ctx); ist->is_start = 1; return 0; @@ -2110,28 +1485,32 @@ static InputStream *get_input_stream(OutputStream *ost) { if (ost->source_index >= 0) return input_streams[ost->source_index]; - return NULL; -} -static int compare_int64(const void *a, const void *b) -{ - int64_t va = *(int64_t *)a, vb = *(int64_t *)b; - return va < vb ? -1 : va > vb ? +1 : 0; + if (ost->filter) { + FilterGraph *fg = ost->filter->graph; + int i; + + for (i = 0; i < fg->nb_inputs; i++) + if (fg->inputs[i]->ist->st->codec->codec_type == ost->st->codec->codec_type) + return fg->inputs[i]->ist; + } + + return NULL; } static void parse_forced_key_frames(char *kf, OutputStream *ost, AVCodecContext *avctx) { char *p; - int n = 1, i, size, index = 0; - int64_t t, *pts; + int n = 1, i; + int64_t t; for (p = kf; *p; p++) if (*p == ',') n++; - size = n; - pts = av_malloc(sizeof(*pts) * size); - if (!pts) { + ost->forced_kf_count = n; + ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n); + if (!ost->forced_kf_pts) { av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); exit_program(1); } @@ -2143,58 +1522,11 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost, if (next) *next++ = 0; - if (!memcmp(p, "chapters", 8)) { - - AVFormatContext *avf = output_files[ost->file_index]->ctx; - int j; - - if (avf->nb_chapters > INT_MAX - size || - !(pts = av_realloc_f(pts, size += avf->nb_chapters - 1, - sizeof(*pts)))) { - av_log(NULL, AV_LOG_FATAL, - "Could not allocate forced key frames array.\n"); - exit_program(1); - } - t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0; - t = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); - - for (j = 0; j < avf->nb_chapters; j++) { - AVChapter *c = avf->chapters[j]; - av_assert1(index < size); - pts[index++] = av_rescale_q(c->start, c->time_base, - avctx->time_base) + t; - } - - } else { - - t = parse_time_or_die("force_key_frames", p, 1); - av_assert1(index < size); - pts[index++] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); - - } + t = parse_time_or_die("force_key_frames", p, 1); + ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); p = next; } - - av_assert0(index == size); - qsort(pts, size, sizeof(*pts), compare_int64); - ost->forced_kf_count = size; - ost->forced_kf_pts = pts; -} - -static void report_new_stream(int input_index, AVPacket *pkt) -{ - InputFile *file = input_files[input_index]; - AVStream *st = file->ctx->streams[pkt->stream_index]; - - if (pkt->stream_index < file->nb_streams_warn) - return; - av_log(file->ctx, AV_LOG_WARNING, - "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n", - av_get_media_type_string(st->codec->codec_type), - input_index, pkt->stream_index, - pkt->pos, av_ts2timestr(pkt->dts, &st->time_base)); - file->nb_streams_warn = pkt->stream_index + 1; } static int transcode_init(void) @@ -2207,21 +1539,6 @@ static int transcode_init(void) char error[1024]; int want_sdp = 1; - for (i = 0; i < nb_filtergraphs; i++) { - FilterGraph *fg = filtergraphs[i]; - for (j = 0; j < fg->nb_outputs; j++) { - OutputFilter *ofilter = fg->outputs[j]; - if (!ofilter->ost || ofilter->ost->source_index >= 0) - continue; - if (fg->nb_inputs != 1) - continue; - for (k = nb_input_streams-1; k >= 0 ; k--) - if (fg->inputs[0]->ist == input_streams[k]) - break; - ofilter->ost->source_index = k; - } - } - /* init framerate emulation */ for (i = 0; i < nb_input_files; i++) { InputFile *ifile = input_files[i]; @@ -2263,15 +1580,6 @@ static int transcode_init(void) ost->st->disposition = ist->st->disposition; codec->bits_per_raw_sample = icodec->bits_per_raw_sample; codec->chroma_sample_location = icodec->chroma_sample_location; - } else { - for (j=0; jnb_streams; j++) { - AVStream *st = oc->streams[j]; - if (st != ost->st && st->codec->codec_type == codec->codec_type) - break; - } - if (j == oc->nb_streams) - if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO) - ost->st->disposition = AV_DISPOSITION_DEFAULT; } if (ost->stream_copy) { @@ -2291,10 +1599,9 @@ static int transcode_init(void) codec->codec_type = icodec->codec_type; if (!codec->codec_tag) { - unsigned int codec_tag; if (!oc->oformat->codec_tag || av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == codec->codec_id || - !av_codec_get_tag2(oc->oformat->codec_tag, icodec->codec_id, &codec_tag)) + av_codec_get_tag(oc->oformat->codec_tag, icodec->codec_id) <= 0) codec->codec_tag = icodec->codec_tag; } @@ -2307,59 +1614,14 @@ static int transcode_init(void) return AVERROR(ENOMEM); } memcpy(codec->extradata, icodec->extradata, icodec->extradata_size); - codec->extradata_size= icodec->extradata_size; - codec->bits_per_coded_sample = icodec->bits_per_coded_sample; - - codec->time_base = ist->st->time_base; - /* - * Avi is a special case here because it supports variable fps but - * having the fps and timebase differe significantly adds quite some - * overhead - */ - if(!strcmp(oc->oformat->name, "avi")) { - if ( copy_tb<0 && av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate) - && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(ist->st->time_base) - && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(icodec->time_base) - && av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(icodec->time_base) < 1.0/500 - || copy_tb==2){ - codec->time_base.num = ist->st->r_frame_rate.den; - codec->time_base.den = 2*ist->st->r_frame_rate.num; - codec->ticks_per_frame = 2; - } else if ( copy_tb<0 && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base) - && av_q2d(ist->st->time_base) < 1.0/500 - || copy_tb==0){ - codec->time_base = icodec->time_base; - codec->time_base.num *= icodec->ticks_per_frame; - codec->time_base.den *= 2; - codec->ticks_per_frame = 2; - } - } else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS) - && strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp") - && strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod") - && strcmp(oc->oformat->name, "f4v") - ) { - if( copy_tb<0 && icodec->time_base.den - && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) - && av_q2d(ist->st->time_base) < 1.0/500 - || copy_tb==0){ - codec->time_base = icodec->time_base; - codec->time_base.num *= icodec->ticks_per_frame; - } - } - if ( codec->codec_tag == AV_RL32("tmcd") - && icodec->time_base.num < icodec->time_base.den - && icodec->time_base.num > 0 - && 121LL*icodec->time_base.num > icodec->time_base.den) { - codec->time_base = icodec->time_base; - } - - if (ist && !ost->frame_rate.num) - ost->frame_rate = ist->framerate; - if(ost->frame_rate.num) - codec->time_base = av_inv_q(ost->frame_rate); - - av_reduce(&codec->time_base.num, &codec->time_base.den, - codec->time_base.num, codec->time_base.den, INT_MAX); + codec->extradata_size = icodec->extradata_size; + if (!copy_tb) { + codec->time_base = icodec->time_base; + codec->time_base.num *= icodec->ticks_per_frame; + av_reduce(&codec->time_base.num, &codec->time_base.den, + codec->time_base.num, codec->time_base.den, INT_MAX); + } else + codec->time_base = ist->st->time_base; ost->parser = av_parser_init(codec->codec_id); @@ -2375,30 +1637,19 @@ static int transcode_init(void) codec->frame_size = icodec->frame_size; codec->audio_service_type = icodec->audio_service_type; codec->block_align = icodec->block_align; - codec->delay = icodec->delay; - if((codec->block_align == 1 || codec->block_align == 1152 || codec->block_align == 576) && codec->codec_id == AV_CODEC_ID_MP3) - codec->block_align= 0; - if(codec->codec_id == AV_CODEC_ID_AC3) - codec->block_align= 0; break; case AVMEDIA_TYPE_VIDEO: codec->pix_fmt = icodec->pix_fmt; codec->width = icodec->width; codec->height = icodec->height; codec->has_b_frames = icodec->has_b_frames; - if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option - sar = - av_mul_q(ost->frame_aspect_ratio, - (AVRational){ codec->height, codec->width }); - av_log(NULL, AV_LOG_WARNING, "Overriding aspect ratio " - "with stream copy may produce invalid files\n"); - } + if (ost->frame_aspect_ratio) + sar = av_d2q(ost->frame_aspect_ratio * codec->height / codec->width, 255); else if (ist->st->sample_aspect_ratio.num) sar = ist->st->sample_aspect_ratio; else sar = icodec->sample_aspect_ratio; ost->st->sample_aspect_ratio = codec->sample_aspect_ratio = sar; - ost->st->avg_frame_rate = ist->st->avg_frame_rate; break; case AVMEDIA_TYPE_SUBTITLE: codec->width = icodec->width; @@ -2411,20 +1662,46 @@ static int transcode_init(void) abort(); } } else { - if (!ost->enc) - ost->enc = avcodec_find_encoder(codec->codec_id); if (!ost->enc) { /* should only happen when a default codec is not present. */ - snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d:%d", - avcodec_get_name(ost->st->codec->codec_id), ost->file_index, ost->index); + snprintf(error, sizeof(error), "Automatic encoder selection " + "failed for output stream #%d:%d. Default encoder for " + "format %s is probably disabled. Please choose an " + "encoder manually.\n", ost->file_index, ost->index, + oc->oformat->name); ret = AVERROR(EINVAL); goto dump_format; } if (ist) - ist->decoding_needed++; + ist->decoding_needed = 1; ost->encoding_needed = 1; + /* + * We want CFR output if and only if one of those is true: + * 1) user specified output framerate with -r + * 2) user specified -vsync cfr + * 3) output format is CFR and the user didn't force vsync to + * something else than CFR + * + * in such a case, set ost->frame_rate + */ + if (codec->codec_type == AVMEDIA_TYPE_VIDEO && + !ost->frame_rate.num && ist && + (video_sync_method == VSYNC_CFR || + (video_sync_method == VSYNC_AUTO && + !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS))))) { + ost->frame_rate = ist->framerate.num ? ist->framerate : + ist->st->avg_frame_rate.num ? + ist->st->avg_frame_rate : + (AVRational){25, 1}; + + if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) { + int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates); + ost->frame_rate = ost->enc->supported_framerates[idx]; + } + } + if (!ost->filter && (codec->codec_type == AVMEDIA_TYPE_VIDEO || codec->codec_type == AVMEDIA_TYPE_AUDIO)) { @@ -2436,102 +1713,45 @@ static int transcode_init(void) } } - if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (ost->filter && !ost->frame_rate.num) - ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter); - if (ist && !ost->frame_rate.num) - ost->frame_rate = ist->framerate; - if (ist && !ost->frame_rate.num) - ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1}; -// ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1}; - if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) { - int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates); - ost->frame_rate = ost->enc->supported_framerates[idx]; - } - } - switch (codec->codec_type) { case AVMEDIA_TYPE_AUDIO: codec->sample_fmt = ost->filter->filter->inputs[0]->format; codec->sample_rate = ost->filter->filter->inputs[0]->sample_rate; codec->channel_layout = ost->filter->filter->inputs[0]->channel_layout; - codec->channels = avfilter_link_get_channels(ost->filter->filter->inputs[0]); + codec->channels = av_get_channel_layout_nb_channels(codec->channel_layout); codec->time_base = (AVRational){ 1, codec->sample_rate }; break; case AVMEDIA_TYPE_VIDEO: - codec->time_base = av_inv_q(ost->frame_rate); - if (ost->filter && !(codec->time_base.num && codec->time_base.den)) - codec->time_base = ost->filter->filter->inputs[0]->time_base; - if ( av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH - && (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){ - av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n" - "Please consider specifying a lower framerate, a different muxer or -vsync 2\n"); - } - for (j = 0; j < ost->forced_kf_count; j++) - ost->forced_kf_pts[j] = av_rescale_q(ost->forced_kf_pts[j], - AV_TIME_BASE_Q, - codec->time_base); + codec->time_base = ost->filter->filter->inputs[0]->time_base; codec->width = ost->filter->filter->inputs[0]->w; codec->height = ost->filter->filter->inputs[0]->h; codec->sample_aspect_ratio = ost->st->sample_aspect_ratio = - ost->frame_aspect_ratio.num ? // overridden by the -aspect cli option - av_mul_q(ost->frame_aspect_ratio, (AVRational){ codec->height, codec->width }) : + ost->frame_aspect_ratio ? // overridden by the -aspect cli option + av_d2q(ost->frame_aspect_ratio * codec->height/codec->width, 255) : ost->filter->filter->inputs[0]->sample_aspect_ratio; - if (!strncmp(ost->enc->name, "libx264", 7) && - codec->pix_fmt == AV_PIX_FMT_NONE && - ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P) - av_log(NULL, AV_LOG_WARNING, - "No pixel format specified, %s for H.264 encoding chosen.\n" - "Use -pix_fmt yuv420p for compatibility with outdated media players.\n", - av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format)); - if (!strncmp(ost->enc->name, "mpeg2video", 10) && - codec->pix_fmt == AV_PIX_FMT_NONE && - ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P) - av_log(NULL, AV_LOG_WARNING, - "No pixel format specified, %s for MPEG-2 encoding chosen.\n" - "Use -pix_fmt yuv420p for compatibility with outdated media players.\n", - av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format)); codec->pix_fmt = ost->filter->filter->inputs[0]->format; - if (!icodec || - codec->width != icodec->width || - codec->height != icodec->height || - codec->pix_fmt != icodec->pix_fmt) { - codec->bits_per_raw_sample = frame_bits_per_raw_sample; + if (icodec && + (codec->width != icodec->width || + codec->height != icodec->height || + codec->pix_fmt != icodec->pix_fmt)) { + codec->bits_per_raw_sample = 0; } - if (ost->forced_keyframes) { - if (!strncmp(ost->forced_keyframes, "expr:", 5)) { - ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5, - forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, - "Invalid force_key_frames expression '%s'\n", ost->forced_keyframes+5); - return ret; - } - ost->forced_keyframes_expr_const_values[FKF_N] = 0; - ost->forced_keyframes_expr_const_values[FKF_N_FORCED] = 0; - ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] = NAN; - ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] = NAN; - } else { - parse_forced_key_frames(ost->forced_keyframes, ost, ost->st->codec); - } - } + if (ost->forced_keyframes) + parse_forced_key_frames(ost->forced_keyframes, ost, + ost->st->codec); break; case AVMEDIA_TYPE_SUBTITLE: codec->time_base = (AVRational){1, 1000}; - if (!codec->width) { - codec->width = input_streams[ost->source_index]->st->codec->width; - codec->height = input_streams[ost->source_index]->st->codec->height; - } break; default: abort(); break; } /* two pass mode */ - if (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) { + if ((codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) { char logfilename[1024]; FILE *f; @@ -2542,7 +1762,15 @@ static int transcode_init(void) if (!strcmp(ost->enc->name, "libx264")) { av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE); } else { - if (codec->flags & CODEC_FLAG_PASS2) { + if (codec->flags & CODEC_FLAG_PASS1) { + f = fopen(logfilename, "wb"); + if (!f) { + av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n", + logfilename, strerror(errno)); + exit_program(1); + } + ost->logfile = f; + } else { char *logbuffer; size_t logbuffer_size; if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) { @@ -2552,15 +1780,6 @@ static int transcode_init(void) } codec->stats_in = logbuffer; } - if (codec->flags & CODEC_FLAG_PASS1) { - f = av_fopen_utf8(logfilename, "wb"); - if (!f) { - av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n", - logfilename, strerror(errno)); - exit_program(1); - } - ost->logfile = f; - } } } } @@ -2576,8 +1795,7 @@ static int transcode_init(void) if ((ist = get_input_stream(ost))) dec = ist->st->codec; if (dec && dec->subtitle_header) { - /* ASS code assumes this buffer is null terminated so add extra byte. */ - ost->st->codec->subtitle_header = av_mallocz(dec->subtitle_header_size + 1); + ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size); if (!ost->st->codec->subtitle_header) { ret = AVERROR(ENOMEM); goto dump_format; @@ -2594,14 +1812,10 @@ static int transcode_init(void) ost->file_index, ost->index); goto dump_format; } - if (ost->enc->type == AVMEDIA_TYPE_AUDIO && - !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) - av_buffersink_set_frame_size(ost->filter->filter, - ost->st->codec->frame_size); assert_avoptions(ost->opts); if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000) av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low." - " It takes bits/s as argument, not kbits/s\n"); + "It takes bits/s as argument, not kbits/s\n"); extra_size += ost->st->codec->extradata_size; } else { av_opt_set_dict(ost->st->codec, &ost->opts); @@ -2610,13 +1824,8 @@ static int transcode_init(void) /* init input streams */ for (i = 0; i < nb_input_streams; i++) - if ((ret = init_input_stream(i, error, sizeof(error))) < 0) { - for (i = 0; i < nb_output_streams; i++) { - ost = output_streams[i]; - avcodec_close(ost->st->codec); - } + if ((ret = init_input_stream(i, error, sizeof(error))) < 0) goto dump_format; - } /* discard unused programs */ for (i = 0; i < nb_input_files; i++) { @@ -2648,7 +1857,7 @@ static int transcode_init(void) ret = AVERROR(EINVAL); goto dump_format; } -// assert_avoptions(output_files[i]->opts); + assert_avoptions(output_files[i]->opts); if (strcmp(oc->oformat->name, "rtp")) { want_sdp = 0; } @@ -2745,7 +1954,7 @@ static int need_output(void) if (ost->frame_number >= ost->max_frames) { int j; for (j = 0; j < of->ctx->nb_streams; j++) - close_output_stream(output_streams[of->ost_index + j]); + output_streams[of->ost_index + j]->finished = 1; continue; } @@ -2755,124 +1964,27 @@ static int need_output(void) return 0; } -/** - * Select the output stream to process. - * - * @return selected output stream, or NULL if none available - */ -static OutputStream *choose_output(void) +static InputFile *select_input_file(void) { + InputFile *ifile = NULL; + int64_t ipts_min = INT64_MAX; int i; - int64_t opts_min = INT64_MAX; - OutputStream *ost_min = NULL; - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; - int64_t opts = av_rescale_q(ost->st->cur_dts, ost->st->time_base, - AV_TIME_BASE_Q); - if (!ost->unavailable && !ost->finished && opts < opts_min) { - opts_min = opts; - ost_min = ost; - } - } - return ost_min; -} + for (i = 0; i < nb_input_streams; i++) { + InputStream *ist = input_streams[i]; + int64_t ipts = ist->last_dts; -static int check_keyboard_interaction(int64_t cur_time) -{ - int i, ret, key; - static int64_t last_time; - if (received_nb_signals) - return AVERROR_EXIT; - /* read_key() returns 0 on EOF */ - if(cur_time - last_time >= 100000 && !run_as_daemon){ - key = read_key(); - last_time = cur_time; - }else - key = -1; - if (key == 'q') - return AVERROR_EXIT; - if (key == '+') av_log_set_level(av_log_get_level()+10); - if (key == '-') av_log_set_level(av_log_get_level()-10); - if (key == 's') qp_hist ^= 1; - if (key == 'h'){ - if (do_hex_dump){ - do_hex_dump = do_pkt_dump = 0; - } else if(do_pkt_dump){ - do_hex_dump = 1; - } else - do_pkt_dump = 1; - av_log_set_level(AV_LOG_DEBUG); - } - if (key == 'c' || key == 'C'){ - char buf[4096], target[64], command[256], arg[256] = {0}; - double time; - int k, n = 0; - fprintf(stderr, "\nEnter command: |all