From eb640669b2f51f4f8936a60cbb9668502a414863 Mon Sep 17 00:00:00 2001 From: tkirby Date: Tue, 24 Mar 2009 21:41:51 +0000 Subject: [PATCH] remove errant copy git-svn-id: https://ffmpeg-php.svn.sourceforge.net/svnroot/ffmpeg-php/trunk/ffmpeg-php@665 f31480fa-141b-0410-8f85-e1b837e7f62b --- ffmpeg-php/CREDITS | 3 - ffmpeg-php/ChangeLog | 284 -- ffmpeg-php/EXPERIMENTAL | 2 - ffmpeg-php/INSTALL | 133 - ffmpeg-php/LICENSE | 340 --- ffmpeg-php/TODO | 1 - ffmpeg-php/config.m4 | 115 - ffmpeg-php/ffmpeg-php.c | 182 -- ffmpeg-php/ffmpeg_errorhandler.c | 79 - ffmpeg-php/ffmpeg_errorhandler.h | 38 - ffmpeg-php/ffmpeg_frame.c | 502 ---- ffmpeg-php/ffmpeg_frame.h | 96 - ffmpeg-php/ffmpeg_movie.c | 1491 ----------- ffmpeg-php/ffmpeg_movie.h | 79 - ffmpeg-php/ffmpeg_tools.c | 98 - ffmpeg-php/ffmpeg_tools.h | 55 - ffmpeg-php/gd.h | 686 ----- ffmpeg-php/gd_io.h | 43 - ffmpeg-php/php_ffmpeg.h | 105 - ffmpeg-php/run-tests.php | 2328 ----------------- ffmpeg-php/test_ffmpeg.php | 106 - ffmpeg-php/tests/getAudioBitRate.phpt | 11 - ffmpeg-php/tests/getAudioChannels.phpt | 11 - ffmpeg-php/tests/getAudioCodec.phpt | 11 - ffmpeg-php/tests/getAudioSampleRate.phpt | 11 - ffmpeg-php/tests/getAudioStreamId.phpt | 11 - ffmpeg-php/tests/getBitRate.phpt | 11 - ffmpeg-php/tests/getDuration.phpt | 11 - ffmpeg-php/tests/getFileName.phpt | 11 - ffmpeg-php/tests/getFrame.phpt | 30 - ffmpeg-php/tests/getFrameCount.phpt | 11 - ffmpeg-php/tests/getFrameHeight.phpt | 11 - ffmpeg-php/tests/getFrameNumber.phpt | 14 - ffmpeg-php/tests/getFrameRate.phpt | 11 - ffmpeg-php/tests/getFrameWidth.phpt | 11 - ffmpeg-php/tests/getFramesBackwards.phpt | 264 -- ffmpeg-php/tests/getFramesForward.phpt | 264 -- .../tests/getFramesForwardPassedEnd.phpt | 269 -- ffmpeg-php/tests/getFramesNoArg.phpt | 267 -- ffmpeg-php/tests/getID3Info.phpt | 22 - ffmpeg-php/tests/getNextKeyFrame.phpt | 266 -- ffmpeg-php/tests/getPTS.phpt | 259 -- ffmpeg-php/tests/getPixelAspectRatio.phpt | 12 - ffmpeg-php/tests/getPixelFormat.phpt | 11 - ffmpeg-php/tests/getVideoBitRate.phpt | 11 - ffmpeg-php/tests/getVideoCodec.phpt | 11 - ffmpeg-php/tests/getVideoStreamId.phpt | 11 - ffmpeg-php/tests/hasAudio.phpt | 11 - ffmpeg-php/tests/isKeyFrame.phpt | 267 -- ffmpeg-php/tests/persistentMovie.phpt | 14 - .../test_media/16Hz-20kHz-Exp-1f-5sec.mp3 | Bin 43008 -> 0 bytes ffmpeg-php/tests/test_media/robot.avi | Bin 220738 -> 0 bytes 52 files changed, 8901 deletions(-) delete mode 100644 ffmpeg-php/CREDITS delete mode 100644 ffmpeg-php/ChangeLog delete mode 100644 ffmpeg-php/EXPERIMENTAL delete mode 100644 ffmpeg-php/INSTALL delete mode 100644 ffmpeg-php/LICENSE delete mode 100644 ffmpeg-php/TODO delete mode 100644 ffmpeg-php/config.m4 delete mode 100644 ffmpeg-php/ffmpeg-php.c delete mode 100644 ffmpeg-php/ffmpeg_errorhandler.c delete mode 100644 ffmpeg-php/ffmpeg_errorhandler.h delete mode 100644 ffmpeg-php/ffmpeg_frame.c delete mode 100644 ffmpeg-php/ffmpeg_frame.h delete mode 100644 ffmpeg-php/ffmpeg_movie.c delete mode 100644 ffmpeg-php/ffmpeg_movie.h delete mode 100644 ffmpeg-php/ffmpeg_tools.c delete mode 100644 ffmpeg-php/ffmpeg_tools.h delete mode 100644 ffmpeg-php/gd.h delete mode 100644 ffmpeg-php/gd_io.h delete mode 100644 ffmpeg-php/php_ffmpeg.h delete mode 100644 ffmpeg-php/run-tests.php delete mode 100644 ffmpeg-php/test_ffmpeg.php delete mode 100644 ffmpeg-php/tests/getAudioBitRate.phpt delete mode 100644 ffmpeg-php/tests/getAudioChannels.phpt delete mode 100644 ffmpeg-php/tests/getAudioCodec.phpt delete mode 100644 ffmpeg-php/tests/getAudioSampleRate.phpt delete mode 100644 ffmpeg-php/tests/getAudioStreamId.phpt delete mode 100644 ffmpeg-php/tests/getBitRate.phpt delete mode 100644 ffmpeg-php/tests/getDuration.phpt delete mode 100644 ffmpeg-php/tests/getFileName.phpt delete mode 100644 ffmpeg-php/tests/getFrame.phpt delete mode 100644 ffmpeg-php/tests/getFrameCount.phpt delete mode 100644 ffmpeg-php/tests/getFrameHeight.phpt delete mode 100644 ffmpeg-php/tests/getFrameNumber.phpt delete mode 100644 ffmpeg-php/tests/getFrameRate.phpt delete mode 100644 ffmpeg-php/tests/getFrameWidth.phpt delete mode 100644 ffmpeg-php/tests/getFramesBackwards.phpt delete mode 100644 ffmpeg-php/tests/getFramesForward.phpt delete mode 100644 ffmpeg-php/tests/getFramesForwardPassedEnd.phpt delete mode 100644 ffmpeg-php/tests/getFramesNoArg.phpt delete mode 100644 ffmpeg-php/tests/getID3Info.phpt delete mode 100644 ffmpeg-php/tests/getNextKeyFrame.phpt delete mode 100644 ffmpeg-php/tests/getPTS.phpt delete mode 100644 ffmpeg-php/tests/getPixelAspectRatio.phpt delete mode 100644 ffmpeg-php/tests/getPixelFormat.phpt delete mode 100644 ffmpeg-php/tests/getVideoBitRate.phpt delete mode 100644 ffmpeg-php/tests/getVideoCodec.phpt delete mode 100644 ffmpeg-php/tests/getVideoStreamId.phpt delete mode 100644 ffmpeg-php/tests/hasAudio.phpt delete mode 100644 ffmpeg-php/tests/isKeyFrame.phpt delete mode 100644 ffmpeg-php/tests/persistentMovie.phpt delete mode 100644 ffmpeg-php/tests/test_media/16Hz-20kHz-Exp-1f-5sec.mp3 delete mode 100644 ffmpeg-php/tests/test_media/robot.avi diff --git a/ffmpeg-php/CREDITS b/ffmpeg-php/CREDITS deleted file mode 100644 index 39b83ee..0000000 --- a/ffmpeg-php/CREDITS +++ /dev/null @@ -1,3 +0,0 @@ -Todd Kirby (ffmpeg.php AT gmail.com) -Martin Prangl (martin.prangl AT itec.uni-klu.ac.at) -Alexey Zakhlestin diff --git a/ffmpeg-php/ChangeLog b/ffmpeg-php/ChangeLog deleted file mode 100644 index 9e7bb82..0000000 --- a/ffmpeg-php/ChangeLog +++ /dev/null @@ -1,284 +0,0 @@ -ChangeLog for ffmpeg-php (ffmpeg-php.sourceforge.net) - -version 0.6.1 (2/25/2009) - Bug Fixes - * Fixed building on php4 - -version 0.6.0 (10/15/2008) - New Features: - * Support for ffmpeg swscale API - - API Changes: - * Removed obsolete resize() and crop() functions. These operations are - more flexibly done using the gd commands. - * Removed animated gif class since it was way out of date and the - quality of animated gifs created by ffmpeg sucks anyway - - Bug Fixes: - * Added check to ensure that gd loads before ffmpeg-php if both are - compiled as extensions. - * Replaced large mp3 test file with smaller sample to avoid copyright - issues and reduce package size. - * Convert from deprecated img_* functions to swscale. - * Builds against php4 correctly again. - -version 0.5.3 (05/30/2008) - New Features: - * Added 'ffmpeg.show_warnings' ini flag to control whether ffmpeg - warnings are converted to php warnings. - * Applied patch to add getAudioStreamId and getVideoStreamId functions - -version 0.5.2.1 (04/03/2008) - - Bug Fixes: - * Minor build fixes and cleanups - -version 0.5.2 (04/02/2008) - - Bug Fixes: - * ffmpeg-php should compile on macos-x now - * Failure to find the proper codec is not a fatal error anymore - * Updated build script to deal with new ffmpeg include file layout. - - - New Features: - * Added gd image bounds checking. - * Added config flag to skip the compile-time gd check. - * ffmpeg's logs are mapped to php's warnings and notices (no more stderr pollution) - -version 0.5.1 (06/11/2007) - - Bug Fixes: - * Fixed some of the tests (Thanks to Raphael Geissert for the patch) - * Improved build process (Thanks to Raphael Geissert for the suggestions) - * Fixed the test script so it won't generate warnings when video/audio - stream is missing. - - New Features: - * Added $movie->hasVideo() function to test for video stream. - * Copyright updated for better compatibilty with the PHP license. - -version 0.5.0 (09/29/2006) - - Bug Fixes: - * Fixed problem with params to av_open_input_file not getting initialized - correctly. (Thanks to SilverCode for the fix) - -version 0.4.9 (09/04/2006) - - New Features: - * Better error reporting when opening a movie fails - * INSTALL doc clarifications - - Bug Fixes: - * Fixed compilation error in ffmpeg_animated_gif.c when building against - old ffmpeg - - -version 0.4.8 (08/04/2006) - - New Features: - * Added new functions for audio streams: getAudioSampleRate(), - getAudioBitRate() (Martin Prangl) - * Changed getBitRate function to like getAudioSampleRate() and - getAudioBitRate(). Now returns bits per second instead of - calculating kb/s. (To get kb/s just do movie->getBitRate() / 1000 - in php.) (tkirby) - - Bug Fixes: - * Fix possible error in hasAudio calculation if audio stream is the - first stream. (tkirby) - -version 0.4.7 (06/08/2006) - - Bug Fixes: - * Fixed framerate calculation to be compatible with ffmpeg cvs 6/8/06 - (tkirby) - -version 0.4.6 (08/30/2005) - - Bug Fixes: - * Fixed compatiblity with ffmpeg cvs after 7/30/05 or so (tkirby) - -version 0.4.5 (07/12/2005) - Bug Fixes: - * Minor build fixes for older ffmpeg versions (tkirby) - -version 0.4.4 (06/24/2005) - New Features: - * Added ability to create animated gifs via new ffmpeg_animated_gif - class (tkirby) - * Fixed ffmpeg_frame constructor to allow creating ffmpeg_frames from - gd images. This allows to make animated gifs directly from a series - of gd images. I believe this is currently the only way to make - animated gifs using PHP since the bundled version of gd does not - support animated gif creation (tkirby) - * Added flag to php.ini to allow server admins to disable persistent - movies since injudicious use of persistent movies in scripts can eat - up server resources quickly (tkirby) - * Added frame->isKeyFrame() and movie->getNextKeyFrame() methods (tkirby) - * Now displays ffmpeg-php ini values in php_info() table (tkirby) - - Bug Fixes: - * Fixed parsing of 'persistent' boolean flag in ffmpeg_movie constructor - * Fixed segfault when a script tries to read more frames than exist in - a movie. (tkirby) - * Patch to use native time bases. This allows building against libavcodec - build 4754+ (Steve Brown) - * Patch to corrctly init gd before attempting to fetch gd image resources. - This fixes the "togdimage() supplied resource is not a valid Image - resource" error that a few people have reported (Steve Brown) - -version 0.4.3 (03/12/2005) - Bug Fixes: - * Added ability to open movies as persistent resources. This greatly - increases speed of repeatedly accessing the same movie from separate - php scripts. This is still somewhat experimental so don't use it - unless you have a specific need (tkirby) - * Increased strictness of compiler warnings to catch issues like - undefined symbol errors. (tkirby) - * Track frame number within ffmpeg-php since the frame_number variable - in ffmpeg's decoder context seems to give inaccurate results on some - 3GP movies. (tkirby) - * Fixed bug #1099229 - Stride problems if ffmpeg_frame is resized upwards - (tkirby) - * Functions now use safe_emalloc() to avoid possible integer overflows - (tkirby) - * Changed lrint() to a macro to allow compiling on Windows (tkirby) - -version 0.4.2.1 (02/15/2005) - Bug Fixes: - * Fixed error handling when ffmpeg_movie object creation fails (tkirby) - * Fixed undefined symbol error in ffmpeg_output_movie (tkirby) - -version 0.4.2 (01/15/2005) - New Features: - * Added more ID3 methods getAlbum(), getArtist(), getGenre()), - getTrackNumber(), getYear() for audio files. (tkirby) - * Cleaned up to build without gd (tkirby) - * Added ability to build against current ffmpeg cvs (tkirby) - - Bug Fixes: - * Fixed segfault in ffmpeg_movie free when decoder is not found (tkirby) - -version 0.4.1 (01/08/2005) - New Features: - * Added getVideoCodec(), getAudioCodec() and getAudioChannels() functions - per feature request #1097373 (tkirby) - * Added constructor for ffmpeg_frame that allows to create from a gd - image. This won't be all that useful until encoding support is added. - (tkirby) - - Bug Fixes: - * Fixed incorrect error reporting in get_decoder (tkirby) - * Don't error if decoder can't be found, just warn (tkirby) - * Fixed nasty memory leak in free ffmpeg_frame (tkirby) - * Code cleanup (tkirby) - -version 0.4.0a "Festivus" (12/23/2004) - New Features: - * Added ffmpeg_frame object to encapsulate frame specific methods. This - cleans up the explosion of getFrame methods and makes eventual encoding - support easier (tkirby) - - Bug Fixes: - * Fixed bug where image resampling context was not getting freed - (tkirby) - * Fixed bug in getDuration() where duration was return as an int, which - was causing frame counts to be off (tkirby) - -version 0.3.8a (12/15/2004) - New Features: - * Added getFrameIntoImage() function to reuse the same gd image for speed - (tkirby) - - Bug Fixes: - * Fixed bug in getFrameResampled() argument parsing (tkirby) - * Fixed broken alias for getBitRate() function (tkirby) - * Fixed memory leak in gd image allocation function (tkirby) - -version 0.3.7a (12/05/2004) - New Features: - * Added support for PHP5 - - Bug Fixes: - * Fixed incorrect module initialization that was causing segfault in PHP5 - (tkirby) - -version 0.3.6a (12/04/2004) - New Features: - * More malloc optimizations in frame conversion/resampling (tkirby) - * Added cropping support to getFrameResampled() and getFrame() (tkirby) - - Bug Fixes: - * Fixed bug #1079237 getFrame fails when getting the same frame twice - (tkirby) - * Fixed memory leak when freeing ffmpeg_movie objects (tkirby) - * Fixed bug #1078753 cropping doesn't work correctly if image is not - resized (tkirby) - * Fixed bug #1077952 Segfault with multiple calls to getFrameResampled() - (tkirby) - * Fixed tiny memory leak in _php_get_gd_image() (tkirby) - * Added configure warning if trying to build against php 5 since it - is not supported yet. (tkirby) - -version 0.3.5a (11/29/2004): - New Features: - * Can now be built independently of PHP sources. (tkirby) - * Added ebuild goodness for the Gentoo Type/R crowd - (tkirby - Gentoo User :-) - - Bug Fixes: - * Fixed a couple of really stupid conversion bugs in getFrame() and - getFrameResampled() (tkirby) - -version 0.3.4a (11/28/2004): - New Features: - * Added new method getFrameResampled() which returns a frame resized - using ffmpeg's resampling. ffmpeg resmpling IMHO is better than GD's - resampling and will speed up greatly returning say a thumbnail sized - frame since less data has to be copied into the returned GD image. - The only caveat to ffmpeg based resampling is that the width and - height of the resized image must be even numbers (tkirby) - * Initial support for audio only files such as mp3 (tkirby) - * getDuration() now works for mp3 files (tkirby) - * getVideoBitrate() will return bit rate for mp3 files though this will - change in the future when more audio specific methods are added (tkirby) - -version 0.3.3a (11/25/2004): - New Features: - * Added PHP constants for libavcodec version and build numbers (tkirby) - * Added getVideoBitRate() method (tkirby) - * More optimizations for successive calls to getFrame() (tkirby) - - Bug Fixes: - * Don't error if stream params not found since some formats don't need - them (tkirby) - * Return zero if can't get a valid duration for the movie (tkirby) - * Zero out alpha channel when copying frame to gd so gd will not try to - apply alpha when image is passed to gdImageCopyResampled() (tkirby) - * getFrame() no longer bounds checks the framenumber param against - framecount since framecount may not always be accurate (tkirby) - * getFrame() now returns false if the wanted frame is not found instead - of generating an error (tkirby) - -version 0.3.2a (11/22/2004): - New Features: - * Added getPixelFormat() method (tkirby) - * Added hasAudio() method (tkirby) - * Optimized getFrame() method so that reading successive frames is much - faster (tkirby) - * getFrame() can now be called without an argument to get the next frame in - the stream (tkirby) - - Bug Fixes: - * Fixed getFrame() returning one frame off of the requested frame (tkirby) - -version 0.3.1a (11/19/2004): - Bug Fixes: - * Full getFrame() rework, should now work with all ffmpeg movie types - (tkirby) - -version 0.3.0a (11/17/2004): - New Features: - * Initial support for framer() (tkirby) diff --git a/ffmpeg-php/EXPERIMENTAL b/ffmpeg-php/EXPERIMENTAL deleted file mode 100644 index 6ace6d0..0000000 --- a/ffmpeg-php/EXPERIMENTAL +++ /dev/null @@ -1,2 +0,0 @@ -THE FFMPEG-PHP EXTENSION IS EXPERIMENTAL! USE IT AT YOUR OWN RISK :-O - diff --git a/ffmpeg-php/INSTALL b/ffmpeg-php/INSTALL deleted file mode 100644 index 8096157..0000000 --- a/ffmpeg-php/INSTALL +++ /dev/null @@ -1,133 +0,0 @@ -REQUIREMENTS -============ - -ffmpeg-0.4.9pre1 or higher built with the --enable-shared option (ffmpeg svn recommended) -php-5.0.x or higher. For php-4.x.x, use ffmpeg-php-0.5.1 or older. -gd-2.0.x or higher or the version of GD bundled with PHP - -INSTALLATION INSTRUCTIONS -========================= - -These instructions are for Linux since I don't have windows. If you -successfully build on windows, let me know how you did it and I'll update -these instructions. - -INSTALLING FROM A PACKAGE MANAGER ---------------------------------- - -There are prebuilt packages for many Linux distros. - -Gentoo: - emerge ffmpeg-php - -Debian/Ubuntu: - apt-get install php5-ffmpeg - -Other: - check your docs for specific info on how to invoke the package manager. - - -BUILDING FFMPEG ---------------- - -cd /path/to/ffmpeg -./configure --enable-shared --prefix=/usr -make clean && make -[become root] -make install - - -BUILDING FFMPEG-PHP AS A SHARED EXTENSION ------------------------------------------ - -1. Build php if not already built or installed by your distro (See the file INSTALL in your php source directory) - -2. Unpack the archive - - tar -xjf ffmpeg-php.X.x.x.tbz2 -C /path/to/php_sources/ext/ - -3. cd into the ffmpeg extension directory - - cd /path/to/php_sources/ext/ffmpeg-php.X.X.X/ - -4. Run phpize (included with your php install) to build configuration files - - phpize - -5. Configure and build - - ./configure && make - -6. Install the shared extension - - make install (as root) - -If everything went as planned, ffmpeg-php is now installed as a shared library. -You must explicitly load it in your scripts using dl(ffmpeg.so) or if you want -it available to all scripts by default add extension=ffmpeg.so to your php.ini -file which will tell php to load it when starting up. - - -BUILDING FFMPEG-PHP AS PART OF THE PHP BINARY ---------------------------------------------- - -1. Unpack the archive and copy the ffmpeg extension directory into your the php - sources extensions directory - - tar -xjf ffmpeg-php.X.x.x.tbz2 -C /path/to/php_sources/ext/ - -2. Run autoconf to rebuild the php configure script and add the --with-ffmpeg - option - - cd /path/to/php_sources - autoconf - -2. configure php using... - - ./configure --with-ffmpeg=yes - -...and build and install php. - -The ffmpeg-php methods should now be built directly into php and so no need to -explicitly load the extension at runtime. - - -TESTING THE INSTALLATION ------------------------- - -1. Put the directory test_media and test_ffmpeg.php script under your web root -somewhere (put both in the same directory). - -2. Load test_ffmpeg.php into your browser. - -RESULTS: You should get a listing of the methods provided by the ffmpeg-php - module as well as some test output from the methods. - -TROUBLESHOOTING ---------------- - -Q: I get '`gdImage' undeclared or `gdImagePtr''undeclared when I try to - 'make' ffmpeg-php - -A: Your version of php is compiled without gd support. Make sure to use the - '--with-gd' flag when configuring php. If you're sure you have gd but - it is not being detected, reconfigure the build with - '--enable-skip-gd-check' to force ffmpeg-php to build with gd support. - -Q: I get 'avcodec.h: No such file or directory' when I try to 'make' ffmpeg-php - -A: ffmpeg-php can't find ffmpeg header files. Make sure when you configure - ffmpeg you use the '--enable-shared' option and make sure it installs - somewhere where other programs can find the libs/headers. See - 'BUILDING FFMPEG' above for an example. - -Q: Can I just pay you to install it? - -A: Yes. I will install ffmpeg + codecs, ffmpeg-php and flvtool2 on your server for $75 USD. This - is everything you need to convert just about any movie type to flash. - Shoot me an email at ffmpeg.php AT gmail.com if you are interested. - -FURTHER HELP ------------- - -If you get stuck, post a message to the ffmpeg-php google group (http://groups-beta.google.com/group/ffmpeg-php) diff --git a/ffmpeg-php/LICENSE b/ffmpeg-php/LICENSE deleted file mode 100644 index 5b6e7c6..0000000 --- a/ffmpeg-php/LICENSE +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/ffmpeg-php/TODO b/ffmpeg-php/TODO deleted file mode 100644 index c30fc37..0000000 --- a/ffmpeg-php/TODO +++ /dev/null @@ -1 +0,0 @@ -Use ffmpeg's output_example.c to generate video for tests. This will allow to remove the test videos, making the distribution MUCH smaller. diff --git a/ffmpeg-php/config.m4 b/ffmpeg-php/config.m4 deleted file mode 100644 index 674c3dc..0000000 --- a/ffmpeg-php/config.m4 +++ /dev/null @@ -1,115 +0,0 @@ -PHP_ARG_WITH(ffmpeg,for ffmpeg support, -[ --with-ffmpeg[=DIR] Include ffmpeg support (requires ffmpeg >= 0.49.0).]) - -PHP_ARG_ENABLE(skip-gd-check, whether to force gd support in ffmpeg-php, [ --enable-skip-gd-check skip checks for gd libs and assume they are present.], no, no) - -if test "$PHP_SKIP_GD_CHECK" != "no"; then - AC_DEFINE(HAVE_LIBGD20, 1, [Define to 1 if the GD functions are available in php]) -fi - -dnl Determine path to ffmpeg libs -if test "$PHP_FFMPEG" != "no"; then - - dnl Default directories to check for ffmpeg headers - INC_CHECK_DIRS="/usr/local /usr" - - dnl User has specified using --with=ffmpeg=[dir] a directory where we should - dnl look for ffmpeg headers. Prepend this directory to the default dirs so it - dnl gets checked first. - if test "$PHP_FFMPEG" != "yes"; then - INC_CHECK_DIRS="$PHP_FFMPEG $INC_CHECK_DIRS" - fi - - AC_MSG_CHECKING(for ffmpeg headers) - for i in $INC_CHECK_DIRS ; do - if test -f $i/include/ffmpeg/avcodec.h; then - PHP_ADD_INCLUDE($i/include/ffmpeg) - FFMPEG_INC_FOUND=$i/include/ffmpeg - break - elif test -f $i/include/avcodec.h; then - PHP_ADD_INCLUDE($i/include) - FFMPEG_INC_FOUND=$i/include - break - elif test -f $i/include/libavcodec/avcodec.h; then - dnl ffmpeg svn revision 12194 and newer put each header in its own dir - dnl so we have to include them all. - PHP_ADD_INCLUDE($i/include/libavcodec/) - PHP_ADD_INCLUDE($i/include/libavformat/) - PHP_ADD_INCLUDE($i/include/libavutil/) - PHP_ADD_INCLUDE($i/include/libswscale/) - PHP_ADD_INCLUDE($i/include/libavfilter/) - PHP_ADD_INCLUDE($i/include/libavdevice/) - FFMPEG_INC_FOUND=$i/include/libavcodec - break - fi - done - - if test -z "$FFMPEG_INC_FOUND"; then - AC_MSG_RESULT() - AC_MSG_ERROR([ffmpeg headers not found. Make sure ffmpeg is compiled as shared libraries using the --enable-shared option]) - else - AC_MSG_RESULT(...found in $FFMPEG_INC_FOUND) - fi - - - AC_MSG_CHECKING(for ffmpeg libavcodec.so) - for i in $PHP_FFMPEG /usr/local /usr ; do - if test -f $i/lib/libavcodec.so; then - FFMPEG_LIBDIR=$i/lib - fi - dnl PATCH: 1785450 x86_64 support (Bent Nagstrup Terp) - if test -f $i/lib64/libavcodec.so; then - FFMPEG_LIBDIR=$i/lib64 - fi - dnl MacOS-X support (Alexey Zakhlestin) - if test -f $i/lib/libavcodec.dylib; then - FFMPEG_LIBDIR=$i/lib - fi - done - - PHP_ADD_LIBRARY_WITH_PATH(avcodec, $FFMPEG_LIBDIR, FFMPEG_SHARED_LIBADD) - PHP_ADD_LIBRARY_WITH_PATH(avformat, $FFMPEG_LIBDIR, FFMPEG_SHARED_LIBADD) - - - if test -z "$FFMPEG_LIBDIR"; then - AC_MSG_RESULT() - AC_MSG_ERROR(ffmpeg shared libraries not found. Make sure ffmpeg is compiled as shared libraries using the --enable-shared option) - else - dnl For debugging - AC_MSG_RESULT(...found in $FFMPEG_LIBDIR) - fi - - dnl check if libavcodec contains img_convert - dnl if not, that means that libswscale is compiled in - AC_MSG_CHECKING(for ffmpeg swscale support) - SAVED_LIBS=$LIBS - LIBS="$LIBS -lavcodec" - SAVED_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -I $INCLUDES" - - AC_TRY_LINK([ #include ], - [ img_convert(0, 0, 0, 0, 0, 0) ], - [ enable_ffmpeg_swscale=no ], - [ enable_ffmpeg_swscale=yes ] ) - AC_MSG_RESULT($enable_ffmpeg_swscale) - LIBS=$SAVED_LIBS - CFLAGS=$SAVED_CFLAGS - - if test "$enable_ffmpeg_swscale" == yes; then - AC_DEFINE(HAVE_SWSCALER, 1, [Define to 1 if software scaler is compiled into ffmpeg]) - PHP_ADD_LIBRARY_WITH_PATH(swscale, $FFMPEG_LIBDIR, FFMPEG_SHARED_LIBADD) - else - dnl Ignore deprecation warnings that using img_convert generates these days - CFLAGS="$CFLAGS -Wno-deprecated-declarations" - fi - - CFLAGS="$CFLAGS -Wall -fno-strict-aliasing" - - PHP_NEW_EXTENSION(ffmpeg, ffmpeg-php.c ffmpeg_movie.c ffmpeg_frame.c ffmpeg_errorhandler.c ffmpeg_tools.c, $ext_shared,, \\$(GDLIB_CFLAGS)) -dnl PHP_ADD_EXTENSION_DEP(ffmpeg, gd) - - PHP_SUBST(FFMPEG_SHARED_LIBADD) - AC_DEFINE(HAVE_FFMPEG_PHP,1,[ ]) - -dnl PHP_DEBUG_MACRO(test.dbg) -fi diff --git a/ffmpeg-php/ffmpeg-php.c b/ffmpeg-php/ffmpeg-php.c deleted file mode 100644 index 05b8872..0000000 --- a/ffmpeg-php/ffmpeg-php.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" - -#include -#include - -#if HAVE_SWSCALER -#include -#endif - -#include "php_ini.h" -#include "php_globals.h" -#include "ext/standard/info.h" - -#include "php_ffmpeg.h" -#include "ffmpeg_errorhandler.h" - -#define FFMPEG_PHP_VERSION "0.6.1" - -zend_module_entry ffmpeg_module_entry = { -#if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, -#endif - "ffmpeg", - NULL, - PHP_MINIT(ffmpeg), - PHP_MSHUTDOWN(ffmpeg), - NULL, - NULL, - PHP_MINFO(ffmpeg), -#if ZEND_MODULE_API_NO >= 20010901 - FFMPEG_PHP_VERSION, -#endif - STANDARD_MODULE_PROPERTIES -}; - - -#ifdef COMPILE_DL_FFMPEG -ZEND_GET_MODULE(ffmpeg); -#endif - -extern void register_ffmpeg_movie_class(int); -extern void register_ffmpeg_frame_class(int); - -PHP_INI_BEGIN() - PHP_INI_ENTRY("ffmpeg.allow_persistent", "0", PHP_INI_ALL, NULL) - PHP_INI_ENTRY("ffmpeg.show_warnings", "0", PHP_INI_ALL, NULL) -PHP_INI_END() - - -/* {{{ php module init function - */ -PHP_MINIT_FUNCTION(ffmpeg) -{ - /* must be called before using avcodec libraries. */ - avcodec_init(); - - /* register all codecs */ - av_register_all(); - - REGISTER_INI_ENTRIES(); - - if (INI_BOOL("ffmpeg.show_warnings")) { - av_log_set_callback(ffmpeg_errorhandler); - } else { - av_log_set_callback(ffmpeg_hide_errors); - } - - register_ffmpeg_movie_class(module_number); - register_ffmpeg_frame_class(module_number); - - REGISTER_STRING_CONSTANT("FFMPEG_PHP_VERSION_STRING", - FFMPEG_PHP_VERSION, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("FFMPEG_PHP_BUILD_DATE_STRING", - __DATE__ " " __TIME__, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LIBAVCODEC_VERSION_NUMBER", - avcodec_version(), CONST_CS | CONST_PERSISTENT); -#ifdef LIBAVCODEC_BUILD - REGISTER_LONG_CONSTANT("LIBAVCODEC_BUILD_NUMBER", - LIBAVCODEC_BUILD, CONST_CS | CONST_PERSISTENT); -#else - REGISTER_LONG_CONSTANT("LIBAVCODEC_BUILD_NUMBER", - avcodec_build(), CONST_CS | CONST_PERSISTENT); -#endif - -#if HAVE_LIBGD20 - REGISTER_LONG_CONSTANT("FFMPEG_PHP_GD_ENABLED", 1, CONST_CS | CONST_PERSISTENT); -#else - REGISTER_LONG_CONSTANT("FFMPEG_PHP_GD_ENABLED", 0, CONST_CS | CONST_PERSISTENT); -#endif // HAVE_LIBGD20 - - return SUCCESS; -} -/* }}} */ - - -/* {{{ php module shutdown function - */ -PHP_MSHUTDOWN_FUNCTION(ffmpeg) -{ - // TODO: Free any remaining persistent movies here? - - UNREGISTER_INI_ENTRIES(); - - return SUCCESS; -} -/* }}} */ - - -/* {{{ php info function - Add an entry for ffmpeg-php support in phpinfo() */ -PHP_MINFO_FUNCTION(ffmpeg) -{ - php_info_print_table_start(); -// php_info_print_table_header(2, "ffmpeg-php", "enabled"); - php_info_print_table_row(2, "ffmpeg-php version", FFMPEG_PHP_VERSION); - php_info_print_table_row(2, "ffmpeg-php built on", __DATE__ " " __TIME__); -#if HAVE_LIBGD20 - php_info_print_table_row(2, "ffmpeg-php gd support ", "enabled"); -#else - php_info_print_table_row(2, "ffmpeg-php gd support ", "disabled"); -#endif // HAVE_LIBGD20 - php_info_print_table_row(2, "ffmpeg libavcodec version", LIBAVCODEC_IDENT); - php_info_print_table_row(2, "ffmpeg libavformat version", LIBAVFORMAT_IDENT); -#if HAVE_SWSCALER - php_info_print_table_row(2, "ffmpeg swscaler version", LIBSWSCALE_IDENT); -#else - php_info_print_table_row(2, "ffmpeg swscaler", "disabled"); -#endif - php_info_print_table_end(); - - DISPLAY_INI_ENTRIES(); -} -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_errorhandler.c b/ffmpeg-php/ffmpeg_errorhandler.c deleted file mode 100644 index d909999..0000000 --- a/ffmpeg-php/ffmpeg_errorhandler.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Alexey Zakhlestin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#include "php.h" -#include - -/* {{{ ffmpeg_errorhandler() - */ -void ffmpeg_errorhandler(void *ptr, int level, const char *msg, va_list args) -{ - int php_level; - TSRMLS_FETCH(); - - switch (level) { - case AV_LOG_ERROR: - php_level = E_WARNING; - break; - - case AV_LOG_INFO: - case AV_LOG_DEBUG: - default: - php_level = E_NOTICE; - break; - } - - php_verror("", "", php_level, msg, args TSRMLS_CC); -} -/* }}} */ - - -/* {{{ ffmpeg_hide_errors() - */ -void ffmpeg_hide_errors(void *ptr, int level, const char *msg, va_list args) -{ - // NO OP -} -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_errorhandler.h b/ffmpeg-php/ffmpeg_errorhandler.h deleted file mode 100644 index 8118420..0000000 --- a/ffmpeg-php/ffmpeg_errorhandler.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Alexey Zakhlestin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - - -void ffmpeg_errorhandler(void *ptr, int level, const char *msg, va_list args); -void ffmpeg_hide_errors(void *ptr, int level, const char *msg, va_list args); diff --git a/ffmpeg-php/ffmpeg_frame.c b/ffmpeg-php/ffmpeg_frame.c deleted file mode 100644 index d928ded..0000000 --- a/ffmpeg-php/ffmpeg_frame.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#include "php.h" -#include "php_ini.h" -#include "php_globals.h" -#include "ext/standard/info.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php_ffmpeg.h" - -#include "ffmpeg_frame.h" -#include "ffmpeg_tools.h" - -/* - include gd header from local include dir. This is a copy of gd.h that is - distributed with php-5.2.5. It is distributed along with ffmpeg-php to - allow ffmpeg-php to be built without access to the php sources - */ -#if HAVE_LIBGD20 -#include "gd.h" - -#define FFMPEG_PHP_FETCH_IMAGE_RESOURCE(gd_img, ret) { \ - ZEND_GET_RESOURCE_TYPE_ID(le_gd, "gd"); \ - ZEND_FETCH_RESOURCE(gd_img, gdImagePtr, ret, -1, "Image", le_gd); \ -} - -// Borrowed from gd.c -#define gdImageBoundsSafeMacro(im, x, y) (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2)))) - -static int le_gd; // this is only valid after calling - // FFMPEG_PHP_FETCH_IMAGE_RESOURCE() - -#endif // HAVE_LIBGD20 - -int le_ffmpeg_frame; // not static since it is used in ffmpeg_output_movie - -static zend_class_entry *ffmpeg_frame_class_entry_ptr; -zend_class_entry ffmpeg_frame_class_entry; - -/* {{{ ffmpeg_frame methods[] - Methods of the ffmpeg_frame class -*/ -zend_function_entry ffmpeg_frame_class_methods[] = { - - /* object can't be created from user space so no PHP constructor */ - //PHP_ME(ffmpeg_frame, __construct, NULL, 0) - -#if HAVE_LIBGD20 - /* gd methods */ - FFMPEG_PHP_MALIAS(ffmpeg_frame, togdimage, toGDImage, NULL, 0) -#endif // HAVE_LIBGD20 - - /* methods */ - FFMPEG_PHP_MALIAS(ffmpeg_frame, getwidth, getWidth, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_frame, getheight, getHeight, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_frame, iskeyframe, isKeyFrame, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_frame, getpresentationtimestamp, getPresentationTimestamp, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_frame, getpts, getPresentationTimestamp, NULL, 0) - FFMPEG_PHP_END_METHODS -}; -/* }}} */ - - -/* {{{ _php_alloc_ff_frame() - */ -static ff_frame_context* _php_alloc_ff_frame() -{ - ff_frame_context *ff_frame = NULL; - - ff_frame = emalloc(sizeof(ff_frame_context)); - - if (!ff_frame) { - zend_error(E_ERROR, "Error allocating ffmpeg_frame"); - } - - ff_frame->av_frame = NULL; - ff_frame->width = 0; - ff_frame->height = 0; - ff_frame->pixel_format = 0; - - return ff_frame; -} -/* }}} */ - - -/* {{{ proto object _php_create_ffmpeg_frame() - creates an ffmpeg_frame object, adds a ffmpeg_frame resource to the - object, registers the resource and returns a direct pointer to the - resource. - */ -ff_frame_context* _php_create_ffmpeg_frame(INTERNAL_FUNCTION_PARAMETERS) -{ - int ret; - ff_frame_context *ff_frame; - - ff_frame = _php_alloc_ff_frame(); - - ret = ZEND_REGISTER_RESOURCE(NULL, ff_frame, le_ffmpeg_frame); - - object_init_ex(return_value, ffmpeg_frame_class_entry_ptr); - add_property_resource(return_value, "ffmpeg_frame", ret); - return ff_frame; -} -/* }}} */ - - -/* {{{ _php_free_av_frame() - */ -static void _php_free_av_frame(AVFrame *av_frame) -{ - if (av_frame) { - if (av_frame->data[0]) { - av_free(av_frame->data[0]); - av_frame->data[0] = NULL; - } - av_free(av_frame); - } -} -/* }}} */ - - -/* {{{ _php_free_ffmpeg_frame() - */ -static void _php_free_ffmpeg_frame(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - ff_frame_context *ff_frame = (ff_frame_context*)rsrc->ptr; - _php_free_av_frame(ff_frame->av_frame); - efree(ff_frame); -} -/* }}} */ - - -/* {{{ register_ffmpeg_frame_class() - */ -void register_ffmpeg_frame_class(int module_number) -{ - TSRMLS_FETCH(); - - le_ffmpeg_frame = zend_register_list_destructors_ex(_php_free_ffmpeg_frame, - NULL, "ffmpeg_frame", module_number); - - INIT_CLASS_ENTRY(ffmpeg_frame_class_entry, "ffmpeg_frame", - ffmpeg_frame_class_methods); - - /* register ffmpeg frame class */ - ffmpeg_frame_class_entry_ptr = - zend_register_internal_class(&ffmpeg_frame_class_entry TSRMLS_CC); -} -/* }}} */ - - -/* {{{ _php_convert_frame() -*/ -int _php_convert_frame(ff_frame_context *ff_frame_ctx, int dst_fmt) { - AVFrame *src_frame; - AVFrame *dst_frame; - int result = 0; - - if (!ff_frame_ctx->av_frame) { - return -1; - } - - src_frame = ff_frame_ctx->av_frame; - - dst_frame = avcodec_alloc_frame(); - avpicture_alloc((AVPicture*)dst_frame, dst_fmt, ff_frame_ctx->width, - ff_frame_ctx->height); - - result = ffmpeg_img_convert((AVPicture*)dst_frame, dst_fmt, - (AVPicture *)src_frame, - ff_frame_ctx->pixel_format, ff_frame_ctx->width, - ff_frame_ctx->height); - - if (result) { - zend_error(E_ERROR, "Error converting frame"); - goto fail; - } - - ff_frame_ctx->av_frame = dst_frame; - ff_frame_ctx->pixel_format = dst_fmt; - -fail: - _php_free_av_frame(src_frame); - return result; -} -/* }}} */ - -#if HAVE_LIBGD20 - -/* {{{ _php_get_gd_image() - */ -static int _php_get_gd_image(int w, int h) -{ - zval *function_name, *width, *height; - zval **argv[2]; - zend_function *func; - zval *retval; - char *function_cname = "imagecreatetruecolor"; - int ret; - TSRMLS_FETCH(); - - if (zend_hash_find(EG(function_table), function_cname, - strlen(function_cname) + 1, (void **)&func) == FAILURE) { - zend_error(E_ERROR, "Error can't find %s function", function_cname); - } - - MAKE_STD_ZVAL(function_name); - MAKE_STD_ZVAL(width); - MAKE_STD_ZVAL(height); - - ZVAL_STRING(function_name, function_cname, 0); - ZVAL_LONG(width, w); - ZVAL_LONG(height, h); - - argv[0] = &width; - argv[1] = &height; - - if (call_user_function_ex(EG(function_table), NULL, function_name, - &retval, 2, argv, 0, NULL TSRMLS_CC) == FAILURE) { - zend_error(E_ERROR, "Error calling %s function", function_cname); - } - - FREE_ZVAL(function_name); - FREE_ZVAL(width); - FREE_ZVAL(height); - - if (!retval || retval->type != IS_RESOURCE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Error creating GD Image"); - } - - ret = retval->value.lval; - zend_list_addref(ret); - if (retval) { - zval_ptr_dtor(&retval); - } - - return ret; -} -/* }}} */ - - -/* {{{ _php_avframe_to_gd_image() - */ -static int _php_avframe_to_gd_image(AVFrame *frame, gdImage *dest, int width, - int height) -{ - int x, y; - int *src = (int*)frame->data[0]; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - - if (gdImageBoundsSafeMacro(dest, x, y)) { - /* copy pixel to gdimage buffer zeroing the alpha channel */ - dest->tpixels[y][x] = src[x] & 0x00ffffff; - } else { - return -1; - } - } - src += width; - } - return 0; -} -/* }}} */ - - -/* {{{ _php_gd_image_to_avframe() - */ -static int _php_gd_image_to_avframe(gdImage *src, AVFrame *frame, int width, - int height) -{ - int x, y; - int *dest = (int*)frame->data[0]; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - if (gdImageBoundsSafeMacro(src, x, y)) { - dest[x] = src->tpixels[y][x]; - } else { - return -1; - } - } - dest += width; - } - return 0; -} -/* }}} */ - - -/* {{{ proto resource toGDImage() - */ -FFMPEG_PHP_METHOD(ffmpeg_frame, toGDImage) -{ - ff_frame_context *ff_frame; - gdImage *gd_img; - - GET_FRAME_RESOURCE(getThis(), ff_frame); - - _php_convert_frame(ff_frame, PIX_FMT_RGBA); - - return_value->value.lval = _php_get_gd_image(ff_frame->width, - ff_frame->height); - - return_value->type = IS_RESOURCE; - - FFMPEG_PHP_FETCH_IMAGE_RESOURCE(gd_img, &return_value); - - if (_php_avframe_to_gd_image(ff_frame->av_frame, gd_img, - ff_frame->width, ff_frame->height)) { - zend_error(E_ERROR, "failed to convert frame to gd image"); - } -} -/* }}} */ - - -/* {{{ proto object _php_read_frame_from_file(mixed) - */ -/*_php_read_frame_from_file(ff_frame_context *ff_frame, char* filename) -{ - AVFrame *frame = NULL; - AVFormatContext *ic; - AVFormatParameters *ap; - int err; - - // open the input file with generic libav function - err = av_open_input_file(&ic, filename, NULL, 0, ap); - if (err < 0) { - zend_error(E_ERROR, "Can't open image file %d, %d", err, - AVERROR_NOFMT); - } - - -}*/ -/* }}} */ - - -/* {{{ proto object ffmpeg_frame(mixed) - */ -FFMPEG_PHP_METHOD(ffmpeg_frame, ffmpeg_frame) -{ - zval **argv[1]; - AVFrame *frame; - gdImage *gd_img; - ff_frame_context *ff_frame; - int width, height, ret; - - if (ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - /* retrieve argument */ - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), argv) != SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Error parsing arguments"); - } - - ff_frame = _php_alloc_ff_frame(); - - ret = ZEND_REGISTER_RESOURCE(NULL, ff_frame, le_ffmpeg_frame); - - object_init_ex(getThis(), ffmpeg_frame_class_entry_ptr); - add_property_resource(getThis(), "ffmpeg_frame", ret); - - switch (Z_TYPE_PP(argv[0])) { - case IS_STRING: - convert_to_string_ex(argv[0]); - zend_error(E_ERROR, - "Creating an ffmpeg_frame from a file is not implemented\n"); - //_php_read_frame_from_file(ff_frame, Z_STRVAL_PP(argv[0])); - break; - case IS_RESOURCE: - FFMPEG_PHP_FETCH_IMAGE_RESOURCE(gd_img, argv[0]); - - if (!gd_img->trueColor) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "First parameter must be a truecolor gd image."); - } - - width = gdImageSX(gd_img); - height = gdImageSY(gd_img); - - /* create a an av_frame and allocate space for it */ - frame = avcodec_alloc_frame(); - avpicture_alloc((AVPicture*)frame, PIX_FMT_RGBA, width, height); - - /* copy the gd image to the av_frame */ - _php_gd_image_to_avframe(gd_img, frame, width, height); - - /* set the ffmepg_frame to point to this av_frame */ - ff_frame->av_frame = frame; - - /* set the ffpmeg_frame's properties */ - ff_frame->width = width; - ff_frame->height = height; - ff_frame->pixel_format = PIX_FMT_RGBA; - break; - default: - zend_error(E_ERROR, "Invalid argument\n"); - } -} -/* }}} */ - -#endif /* HAVE_LIBGD20 */ - - -/* {{{ proto int getPresentationTimestamp() - */ -FFMPEG_PHP_METHOD(ffmpeg_frame, getPresentationTimestamp) -{ - ff_frame_context *ff_frame; - - GET_FRAME_RESOURCE(getThis(), ff_frame); - - RETURN_DOUBLE((double)ff_frame->pts / AV_TIME_BASE); -} -/* }}} */ - - -/* {{{ proto int isKeyFrame() - */ -FFMPEG_PHP_METHOD(ffmpeg_frame, isKeyFrame) -{ - ff_frame_context *ff_frame; - - GET_FRAME_RESOURCE(getThis(), ff_frame); - - RETURN_LONG(ff_frame->keyframe); -} -/* }}} */ - - -/* {{{ proto int getWidth() - */ -FFMPEG_PHP_METHOD(ffmpeg_frame, getWidth) -{ - ff_frame_context *ff_frame; - - GET_FRAME_RESOURCE(getThis(), ff_frame); - - RETURN_LONG(ff_frame->width); -} -/* }}} */ - - -/* {{{ proto int getHeight() - */ -FFMPEG_PHP_METHOD(ffmpeg_frame, getHeight) -{ - ff_frame_context *ff_frame; - - GET_FRAME_RESOURCE(getThis(), ff_frame); - - RETURN_LONG(ff_frame->height); -} -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_frame.h b/ffmpeg-php/ffmpeg_frame.h deleted file mode 100644 index 10ea566..0000000 --- a/ffmpeg-php/ffmpeg_frame.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#ifndef FFMPEG_FRAME_H -#define FFMPEG_FRAME_H - -#include "php_version.h" - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* object can't be created from user space so no PHP constructor */ -//FFMPEG_PHP_CONSTRUCTOR(ffmpeg_frame, __construct); - -/* frame methods */ -FFMPEG_PHP_METHOD(ffmpeg_frame, getWidth); -FFMPEG_PHP_METHOD(ffmpeg_frame, getHeight); -FFMPEG_PHP_METHOD(ffmpeg_frame, isKeyFrame); -FFMPEG_PHP_METHOD(ffmpeg_frame, getPresentationTimestamp); - -#if HAVE_LIBGD20 -FFMPEG_PHP_METHOD(ffmpeg_frame, toGDImage); -#endif // HAVE_LIBGD20 - -typedef struct { - AVFrame *av_frame; - int width; - int height; - int pixel_format; - int keyframe; - int64_t pts; -} ff_frame_context; - -ff_frame_context* _php_create_ffmpeg_frame(INTERNAL_FUNCTION_PARAMETERS); - -int _php_convert_frame(ff_frame_context *ff_frame, int new_fmt); - -#define GET_FRAME_RESOURCE(ffmpeg_frame_object, ffmpeg_frame) {\ - zval **_tmp_zval;\ - if (zend_hash_find(Z_OBJPROP_P(ffmpeg_frame_object), "ffmpeg_frame",\ - sizeof("ffmpeg_frame"), (void **)&_tmp_zval) == FAILURE) {\ - zend_error(E_ERROR, "Unable to locate ffmpeg_frame resource in this object.");\ - RETURN_FALSE;\ - }\ -\ - ZEND_FETCH_RESOURCE(ffmpeg_frame, ff_frame_context*, _tmp_zval, -1,\ - "ffmpeg_frame", le_ffmpeg_frame);\ -}\ - -#endif // FFMPEG_FRAME_H - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_movie.c b/ffmpeg-php/ffmpeg_movie.c deleted file mode 100644 index 33b127b..0000000 --- a/ffmpeg-php/ffmpeg_movie.c +++ /dev/null @@ -1,1491 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#include "php.h" -#include "php_ini.h" -#include "php_globals.h" -#include "ext/standard/info.h" - -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php_ffmpeg.h" - -#include "ffmpeg_frame.h" -#include "ffmpeg_movie.h" - -#define GET_MOVIE_RESOURCE(ff_movie_ctx) {\ - zval **_tmp_zval;\ - if (zend_hash_find(Z_OBJPROP_P(getThis()), "ffmpeg_movie",\ - sizeof("ffmpeg_movie"), (void **)&_tmp_zval) == FAILURE) {\ - zend_error(E_WARNING, "Invalid ffmpeg_movie object");\ - RETURN_FALSE;\ - }\ -\ - ZEND_FETCH_RESOURCE2(ff_movie_ctx, ff_movie_context*, _tmp_zval, -1,\ - "ffmpeg_movie", le_ffmpeg_movie, le_ffmpeg_pmovie);\ -}\ - -#define LRINT(x) ((long) ((x)+0.5)) - -#if LIBAVFORMAT_BUILD > 4628 -#define GET_CODEC_FIELD(codec, field) codec->field -#define GET_CODEC_PTR(codec) codec -#else -#define GET_CODEC_FIELD(codec, field) codec.field -#define GET_CODEC_PTR(codec) &codec -#endif - -typedef struct { - AVFormatContext *fmt_ctx; - AVCodecContext *codec_ctx[MAX_STREAMS]; - int64_t last_pts; - int frame_number; - long rsrc_id; -} ff_movie_context; - -static zend_class_entry *ffmpeg_movie_class_entry_ptr; -zend_class_entry ffmpeg_movie_class_entry; - -static int le_ffmpeg_movie; -static int le_ffmpeg_pmovie; - -/* {{{ ffmpeg_movie methods[] - Methods of the ffmpeg_movie class -*/ -zend_function_entry ffmpeg_movie_class_methods[] = { - - /* contructor */ - FFMPEG_PHP_ME(ffmpeg_movie, __construct, NULL, 0) - - /* methods */ - FFMPEG_PHP_MALIAS(ffmpeg_movie, getduration, getDuration, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getframecount, getFrameCount, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getframerate, getFrameRate, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getfilename, getFileName, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getcomment, getComment, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, gettitle, getTitle, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getauthor, getAuthor, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getartist, getAuthor, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getcopyright, getCopyright, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getalbum, getAlbum, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getgenre, getGenre, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getyear, getYear, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, gettracknumber, getTrackNumber, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getframewidth, getFrameWidth, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getframeheight, getFrameHeight, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getframenumber, getFrameNumber, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getpixelformat, getPixelFormat, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getbitrate, getBitRate, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, hasaudio, hasAudio, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, hasvideo, hasVideo, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getnextkeyframe, getNextKeyFrame, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getframe, getFrame, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getvideocodec, getVideoCodec, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getaudiocodec, getAudioCodec, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getvideostreamid, getVideoStreamId, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getaudiostreamid, getAudioStreamId, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getaudiochannels, getAudioChannels, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getaudiosamplerate, getAudioSampleRate, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getaudiobitrate, getAudioBitRate, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getvideobitrate, getVideoBitRate, NULL, 0) - FFMPEG_PHP_MALIAS(ffmpeg_movie, getpixelaspectratio, getPixelAspectRatio, NULL, 0) - - FFMPEG_PHP_END_METHODS -}; -/* }}} */ - - -/* {{{ _php_get_stream_index() - */ -static int _php_get_stream_index(AVFormatContext *fmt_ctx, int type) -{ - int i; - - for (i = 0; i < fmt_ctx->nb_streams; i++) { - if (fmt_ctx->streams[i] && - GET_CODEC_FIELD(fmt_ctx->streams[i]->codec, codec_type) == type) { - return i; - } - } - /* stream not found */ - return -1; -} -/* }}} */ - - -/* {{{ _php_get_video_stream() - */ -static AVStream *_php_get_video_stream(AVFormatContext *fmt_ctx) -{ - int i = _php_get_stream_index(fmt_ctx, CODEC_TYPE_VIDEO); - - return i < 0 ? NULL : fmt_ctx->streams[i]; -} -/* }}} */ - - -/* {{{ _php_get_audio_stream() - * TODO: Some containers can have multiple audio streams, so this - * will eventually need to be replaced by something smarter - */ -static AVStream *_php_get_audio_stream(AVFormatContext *fmt_ctx) -{ - int i = _php_get_stream_index(fmt_ctx, CODEC_TYPE_AUDIO); - - return i < 0 ? NULL : fmt_ctx->streams[i]; -} -/* }}} */ - - -static int has_audio(ff_movie_context *ffmovie_ctx) { - return _php_get_audio_stream(ffmovie_ctx->fmt_ctx) != NULL; -} - - -static int has_video(ff_movie_context *ffmovie_ctx) { - return _php_get_video_stream(ffmovie_ctx->fmt_ctx) != NULL; -} - - -/* {{{ _php_get_filename() - */ -static char* _php_get_filename(ff_movie_context *ffmovie_ctx) -{ - return ffmovie_ctx->fmt_ctx->filename; -} -/* }}} */ - - -/* {{{ _php_alloc_ffmovie_ctx() - */ -static ff_movie_context* _php_alloc_ffmovie_ctx(int persistent) -{ - int i; - ff_movie_context *ffmovie_ctx; - - ffmovie_ctx = persistent ? malloc(sizeof(ff_movie_context)) : - emalloc(sizeof(ff_movie_context)); - ffmovie_ctx->fmt_ctx = NULL; - ffmovie_ctx->frame_number = 0; - - for (i = 0; i < MAX_STREAMS; i++) { - ffmovie_ctx->codec_ctx[i] = NULL; - } - - return ffmovie_ctx; -} -/* }}} */ - - -/* {{{ _php_print_av_error() - */ -/* -static void _php_print_av_error(const char *filename, int err) -{ - switch(err) { - case AVERROR_IO: - zend_error(E_WARNING, "%s: I/O error.\n", filename); - break; - case AVERROR_NOMEM: - zend_error(E_WARNING, "%s: Not enough memory.\n", filename); - break; - case AVERROR_NOTSUPP: - zend_error(E_WARNING, "%s: Operation not supported.\n", filename); - break; - - case AVERROR_NUMEXPECTED: - zend_error(E_WARNING, "%s: Incorrect image filename syntax.\n", filename); - break; - case AVERROR_INVALIDDATA: - zend_error(E_WARNING, "%s: Error while parsing header\n", filename); - break; - case AVERROR_NOFMT: - zend_error(E_WARNING, "%s: Unknown format\n", filename); - case AVERROR_UNKNOWN: - // Fall thru to default case - default: - zend_error(E_WARNING, "%s: Error while opening file (%d)\n", filename, err); - break; - } -} -*/ -/* }}} */ - - -/* {{{ _php_open_movie_file() - */ -static int _php_open_movie_file(ff_movie_context *ffmovie_ctx, - char* filename) -{ - if (ffmovie_ctx->fmt_ctx) { - av_close_input_file(ffmovie_ctx->fmt_ctx); - ffmovie_ctx->fmt_ctx = NULL; - } - - /* open the file with generic libav function */ - if (av_open_input_file(&ffmovie_ctx->fmt_ctx, filename, NULL, 0, NULL) < 0) { - return 1; - } - - /* decode the first frames to get the stream parameters. */ - av_find_stream_info(ffmovie_ctx->fmt_ctx); - - return 0; -} -/* }}} */ - - -/* {{{ proto object ffmpeg_movie(string filename) - Constructor for ffmpeg_movie objects - */ -FFMPEG_PHP_CONSTRUCTOR(ffmpeg_movie, __construct) -{ - int persistent = 0, hashkey_length = 0; - char *filename = NULL, *fullpath = NULL, *hashkey = NULL; - zval ***argv; - ff_movie_context *ffmovie_ctx = NULL; - - /* retrieve arguments */ - argv = (zval ***) safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0); - - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), argv) != SUCCESS) { - efree(argv); - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Error parsing arguments"); - } - - switch (ZEND_NUM_ARGS()) { - case 2: - convert_to_boolean_ex(argv[1]); - - if (! INI_BOOL("ffmpeg.allow_persistent") && Z_LVAL_PP(argv[1])) { - zend_error(E_WARNING, - "Persistent movies have been disabled in php.ini"); - break; - } - - persistent = Z_LVAL_PP(argv[1]); - - /* fallthru */ - case 1: - convert_to_string_ex(argv[0]); - filename = Z_STRVAL_PP(argv[0]); - break; - default: - WRONG_PARAM_COUNT; - } - - if (persistent) { - list_entry *le; - /* resolve the fully-qualified path name to use as the hash key */ - fullpath = expand_filepath(filename, NULL TSRMLS_CC); - - hashkey_length = sizeof("ffmpeg-php_")-1 + - strlen(SAFE_STRING(filename)); - hashkey = (char *) emalloc(hashkey_length+1); - snprintf(hashkey, hashkey_length, "ffmpeg-php_%s", - SAFE_STRING(filename)); - - - /* do we have an existing persistent movie? */ - if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, - hashkey_length+1, (void**)&le)) { - int type; - - if (Z_TYPE_P(le) != le_ffmpeg_pmovie) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Failed to retrieve persistent resource"); - } - ffmovie_ctx = (ff_movie_context*)le->ptr; - - /* sanity check to ensure that the resource is still a valid - * regular resource number */ - if (zend_list_find(ffmovie_ctx->rsrc_id, &type) == ffmovie_ctx) { - /* add a reference to the persistent movie */ - zend_list_addref(ffmovie_ctx->rsrc_id); - } else { - //php_error_docref(NULL TSRMLS_CC, E_ERROR, - //"Not a valid persistent movie resource"); - ffmovie_ctx->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, - ffmovie_ctx, le_ffmpeg_pmovie); - } - - } else { /* no existing persistant movie, create one */ - list_entry new_le; - ffmovie_ctx = _php_alloc_ffmovie_ctx(1); - - if (_php_open_movie_file(ffmovie_ctx, filename)) { - zend_error(E_WARNING, "Can't open movie file %s", filename); - efree(argv); - ZVAL_BOOL(getThis(), 0); - RETURN_FALSE; - } - - Z_TYPE(new_le) = le_ffmpeg_pmovie; - new_le.ptr = ffmovie_ctx; - - if (FAILURE == zend_hash_update(&EG(persistent_list), hashkey, - hashkey_length+1, (void *)&new_le, sizeof(list_entry), - NULL)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Failed to register persistent resource"); - } - - ffmovie_ctx->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ffmovie_ctx, - le_ffmpeg_pmovie); - } - - } else { - ffmovie_ctx = _php_alloc_ffmovie_ctx(0); - - if (_php_open_movie_file(ffmovie_ctx, Z_STRVAL_PP(argv[0]))) { - zend_error(E_WARNING, "Can't open movie file %s", - Z_STRVAL_PP(argv[0])); - efree(argv); - ZVAL_BOOL(getThis(), 0); - RETURN_FALSE; - } - - /* pass NULL for resource result since we're not returning the resource - directly, but adding it to the returned object. */ - ffmovie_ctx->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ffmovie_ctx, - le_ffmpeg_movie); - } - - object_init_ex(getThis(), ffmpeg_movie_class_entry_ptr); - add_property_resource(getThis(), "ffmpeg_movie", ffmovie_ctx->rsrc_id); - - efree(argv); - if (fullpath) { - efree(fullpath); - } - if (hashkey) { - efree(hashkey); - } -} -/* }}} */ - - -/* {{{ _php_free_ffmpeg_movie - */ -static void _php_free_ffmpeg_movie(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - int i; - ff_movie_context *ffmovie_ctx = (ff_movie_context*)rsrc->ptr; - - if (ffmovie_ctx->codec_ctx) { - for (i = 0; i < MAX_STREAMS; i++) { - if (ffmovie_ctx->codec_ctx[i]) { - avcodec_close(ffmovie_ctx->codec_ctx[i]); - } - ffmovie_ctx->codec_ctx[i] = NULL; - } - } - - av_close_input_file(ffmovie_ctx->fmt_ctx); - - efree(ffmovie_ctx); -} -/* }}} */ - - -/* {{{ _php_free_ffmpeg_pmovie - */ -static void _php_free_ffmpeg_pmovie(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - /* TODO: Factor into a single free function for pmovie and movie */ - int i; - ff_movie_context *ffmovie_ctx = (ff_movie_context*)rsrc->ptr; - - if (ffmovie_ctx->codec_ctx) { - for (i = 0; i < MAX_STREAMS; i++) { - if (ffmovie_ctx->codec_ctx[i]) { - avcodec_close(ffmovie_ctx->codec_ctx[i]); - } - ffmovie_ctx->codec_ctx[i] = NULL; - } - } - - av_close_input_file(ffmovie_ctx->fmt_ctx); - - free(ffmovie_ctx); -} -/* }}} */ - - -/* {{{ register_ffmpeg_movie_class() - */ -void register_ffmpeg_movie_class(int module_number) -{ - TSRMLS_FETCH(); - - le_ffmpeg_movie = zend_register_list_destructors_ex(_php_free_ffmpeg_movie, - NULL, "ffmpeg_movie", module_number); - - le_ffmpeg_pmovie = zend_register_list_destructors_ex(NULL, - _php_free_ffmpeg_pmovie, "ffmpeg_pmovie", module_number); - - INIT_CLASS_ENTRY(ffmpeg_movie_class_entry, "ffmpeg_movie", - ffmpeg_movie_class_methods); - - /* register ffmpeg movie class */ - ffmpeg_movie_class_entry_ptr = - zend_register_internal_class(&ffmpeg_movie_class_entry TSRMLS_CC); -} -/* }}} */ - - -/* {{{ __php_get_decoder_context() - Opens decoders and gets codec context. Always call this to get a pointer to - the codec context. This allows to postpone codec init until a function that - requires it is called. - */ -static AVCodecContext* _php_get_decoder_context(ff_movie_context *ffmovie_ctx, - int stream_type) -{ - AVCodec *decoder; - int stream_index; - - stream_index = _php_get_stream_index(ffmovie_ctx->fmt_ctx, stream_type); - if (stream_index < 0) { - // FIXME: factor out the conditional. - if (stream_type == CODEC_TYPE_VIDEO) { - zend_error(E_WARNING, "Can't find video stream in %s", - _php_get_filename(ffmovie_ctx)); - return NULL; - } else { - zend_error(E_WARNING, "Can't find audio stream in %s", - _php_get_filename(ffmovie_ctx)); - return NULL; - } - } - - /* check if the codec for this stream is already open */ - if (!ffmovie_ctx->codec_ctx[stream_index]) { - - /* find the decoder */ - decoder = avcodec_find_decoder(GET_CODEC_FIELD( - ffmovie_ctx->fmt_ctx->streams[stream_index]->codec, - codec_id)); - - if (!decoder) { - zend_error(E_ERROR, "Could not find decoder for %s", - _php_get_filename(ffmovie_ctx)); - return NULL; - } - - ffmovie_ctx->codec_ctx[stream_index] = - GET_CODEC_PTR(ffmovie_ctx->fmt_ctx->streams[stream_index]->codec); - - /* open the decoder */ - if (avcodec_open(ffmovie_ctx->codec_ctx[stream_index], decoder) < 0) { - zend_error(E_WARNING, "Could not open codec for %s", _php_get_filename(ffmovie_ctx)); - return NULL; - } - } - return ffmovie_ctx->codec_ctx[stream_index]; -} -/* }}} */ - - -/* {{{ proto string getComment() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getComment) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_STRINGL(ffmovie_ctx->fmt_ctx->comment, - strlen(ffmovie_ctx->fmt_ctx->comment), 1); -} -/* }}} */ - - -/* {{{ proto string getTitle() - * Return title field from movie or title ID3 tag from an MP3 file. - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getTitle) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_STRINGL(ffmovie_ctx->fmt_ctx->title, - strlen(ffmovie_ctx->fmt_ctx->title), 1); -} -/* }}} */ - - -/* {{{ proto string getAuthor() or getArtist() - * Return author field from a movie or artist ID3 tag from am MP3 files. - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAuthor) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_STRINGL(ffmovie_ctx->fmt_ctx->author, - strlen(ffmovie_ctx->fmt_ctx->author), 1); -} -/* }}} */ - - -/* {{{ proto string getCopyright() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getCopyright) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_STRINGL(ffmovie_ctx->fmt_ctx->copyright, - strlen(ffmovie_ctx->fmt_ctx->copyright), 1); -} -/* }}} */ - - -/* {{{ proto string getAlbum() - * Return ID3 album field from an mp3 file - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAlbum) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_STRINGL(ffmovie_ctx->fmt_ctx->album, - strlen(ffmovie_ctx->fmt_ctx->album), 1); -} -/* }}} */ - -/* {{{ proto string getGenre() - * Return ID3 genre field from an mp3 file - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getGenre) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_STRINGL(ffmovie_ctx->fmt_ctx->genre, - strlen(ffmovie_ctx->fmt_ctx->genre), 1); -} -/* }}} */ - - -/* {{{ proto int getTrackNumber() - * Return ID3 track field from an mp3 file - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getTrackNumber) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_LONG(ffmovie_ctx->fmt_ctx->track); -} -/* }}} */ - -/* {{{ proto int getYear() - * Return ID3 year field from an mp3 file - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getYear) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_LONG(ffmovie_ctx->fmt_ctx->year); -} -/* }}} */ - - -/* {{{ _php_get_duration() - */ -static float _php_get_duration(ff_movie_context *ffmovie_ctx) -{ - float duration; - - duration = (float)ffmovie_ctx->fmt_ctx->duration / AV_TIME_BASE; - - if (duration < 0) { - duration = 0.0f; - } - return duration; -} -/* }}} */ - - -/* {{{ proto int getDuration() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getDuration) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_DOUBLE(_php_get_duration(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ _php_get_framerate() - */ -static float _php_get_framerate(ff_movie_context *ffmovie_ctx) -{ - AVStream *st = _php_get_video_stream(ffmovie_ctx->fmt_ctx); - float rate = 0.0f; - - if (!st) { - return rate; - } - -#if LIBAVCODEC_BUILD > 4753 - if (GET_CODEC_FIELD(st->codec, codec_type) == CODEC_TYPE_VIDEO){ - if (st->r_frame_rate.den && st->r_frame_rate.num) { - rate = av_q2d(st->r_frame_rate); - } else { - rate = 1 / av_q2d(GET_CODEC_FIELD(st->codec, time_base)); - } - } - return (float)rate; -#else - return (float)GET_CODEC_FIELD(st->codec, frame_rate) / - GET_CODEC_FIELD(st->codec, frame_rate_base); -#endif -} -/* }}} */ - - -/* {{{ _php_get_framecount() - */ -static long _php_get_framecount(ff_movie_context *ffmovie_ctx) -{ - /* does this movie have a video stream? */ - if (!_php_get_video_stream(ffmovie_ctx->fmt_ctx)) { - return 0; - } - - return LRINT(_php_get_framerate(ffmovie_ctx) * - _php_get_duration(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ proto int getFrameCount() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameCount) -{ - ff_movie_context *ffmovie_ctx; - GET_MOVIE_RESOURCE(ffmovie_ctx); - RETURN_LONG(_php_get_framecount(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ proto int getFrameRate() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameRate) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_DOUBLE(_php_get_framerate(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ proto string getFileName() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFileName) -{ - ff_movie_context *ffmovie_ctx; - char* filename; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - filename = _php_get_filename(ffmovie_ctx); - RETURN_STRINGL(filename, strlen(filename), 1); -} -/* }}} */ - - -/* {{{ _php_get_framewidth() - */ -static int _php_get_framewidth(ff_movie_context *ffmovie_ctx) -{ - AVStream *st = _php_get_video_stream(ffmovie_ctx->fmt_ctx); - - if (!st) { - return 0; - } - - return GET_CODEC_FIELD(st->codec, width); -} -/* }}} */ - - -/* {{{ proto int getFrameWidth() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameWidth) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_LONG(_php_get_framewidth(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ _php_get_frameheight() - */ -static int _php_get_frameheight(ff_movie_context *ffmovie_ctx) -{ - AVStream *st = _php_get_video_stream(ffmovie_ctx->fmt_ctx); - - if (!st) { - return 0; - } - - return GET_CODEC_FIELD(st->codec, height); -} -/* }}} */ - - -/* {{{ proto int getFrameHeight() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameHeight) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_LONG(_php_get_frameheight(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ _php_get_framenumber() - */ -static long _php_get_framenumber(ff_movie_context *ffmovie_ctx) -{ - AVCodecContext *decoder_ctx = NULL; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, CODEC_TYPE_VIDEO); - if (!decoder_ctx) { - return 0; - } - - if (ffmovie_ctx->frame_number <= 0) { - return 1; /* no frames read yet so return the first */ - } else { - return ffmovie_ctx->frame_number; - } -} -/* }}} */ - - -/* {{{ proto resource getFrameNumber() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameNumber) -{ - ff_movie_context *ffmovie_ctx; - int frame_number = 0; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - frame_number =_php_get_framenumber(ffmovie_ctx); - - if (frame_number) { - RETURN_LONG(frame_number); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ _php_get_pixelformat() - */ -static int _php_get_pixelformat(ff_movie_context *ffmovie_ctx) -{ - AVCodecContext *decoder_ctx; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, CODEC_TYPE_VIDEO); - - return decoder_ctx ? decoder_ctx->pix_fmt : 0; -} -/* }}} */ - - -/* {{{ proto int getPixelFormat() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getPixelFormat) -{ - int pix_fmt; - const char *fmt; - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - pix_fmt = _php_get_pixelformat(ffmovie_ctx); - fmt = avcodec_get_pix_fmt_name(pix_fmt); - - if (fmt) { - /* cast const to non-const to keep compiler from complaining, - RETURN_STRINGL just copies so the string won't get overwritten - */ - RETURN_STRINGL((char *)fmt, strlen(fmt), 1); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ _php_get_bitrate() - */ -static int _php_get_bitrate(ff_movie_context *ffmovie_ctx) -{ - return ffmovie_ctx->fmt_ctx->bit_rate; -} -/* }}} */ - - -/* {{{ proto int getBitrate() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getBitRate) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_LONG(_php_get_bitrate(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ proto int hasAudio() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, hasAudio) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_BOOL(has_audio(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ proto int hasVideo() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, hasVideo) -{ - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - RETURN_BOOL(has_video(ffmovie_ctx)); -} -/* }}} */ - - -/* {{{ _php_get_codec_name() - Returns the name of a video or audio codec from a movie - */ -static const char* _php_get_codec_name(ff_movie_context *ffmovie_ctx, int type) -{ - AVCodecContext *decoder_ctx = NULL; - AVCodec *p = NULL; - const char *codec_name; - char buf1[32]; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, type); - if (!decoder_ctx) { - return NULL; - } - - p = avcodec_find_decoder(decoder_ctx->codec_id); - - /* Copied from libavcodec/utils.c::avcodec_string */ - if (p) { - codec_name = p->name; - if (decoder_ctx->codec_id == CODEC_ID_MP3) { - if (decoder_ctx->sub_id == 2) - codec_name = "mp2"; - else if (decoder_ctx->sub_id == 1) - codec_name = "mp1"; - } - } else if (decoder_ctx->codec_id == CODEC_ID_MPEG2TS) { - /* fake mpeg2 transport stream codec (currently not registered) */ - codec_name = "mpeg2ts"; - } else if (decoder_ctx->codec_name[0] != '\0') { - codec_name = decoder_ctx->codec_name; - } else { - /* output avi tags */ - if (decoder_ctx->codec_type == CODEC_TYPE_VIDEO) { - snprintf(buf1, sizeof(buf1), "%c%c%c%c", - decoder_ctx->codec_tag & 0xff, - (decoder_ctx->codec_tag >> 8) & 0xff, - (decoder_ctx->codec_tag >> 16) & 0xff, - (decoder_ctx->codec_tag >> 24) & 0xff); - } else { - snprintf(buf1, sizeof(buf1), "0x%04x", decoder_ctx->codec_tag); - } - codec_name = buf1; - } - - return codec_name; -} -/* }}} */ - - -/* {{{ proto int getVideoCodec() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getVideoCodec) -{ - ff_movie_context *ffmovie_ctx; - char *codec_name; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - codec_name = (char*)_php_get_codec_name(ffmovie_ctx, CODEC_TYPE_VIDEO); - - if (codec_name) { - RETURN_STRINGL(codec_name, strlen(codec_name), 1); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ proto int getAudioCodec() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioCodec) -{ - ff_movie_context *ffmovie_ctx; - char *codec_name; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - codec_name = (char*)_php_get_codec_name(ffmovie_ctx, CODEC_TYPE_AUDIO); - - if (codec_name) { - RETURN_STRINGL(codec_name, strlen(codec_name), 1); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ proto int getVideoStreamId() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getVideoStreamId ) -{ - int stream_id; - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - stream_id= _php_get_stream_index(ffmovie_ctx->fmt_ctx, CODEC_TYPE_VIDEO); - - if( stream_id == -1 ) - { - RETURN_NULL(); - } - else - { - RETURN_LONG(stream_id); - } -} -/* }}} */ - -/* {{{ proto int getAudioStreamId() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioStreamId ) -{ - int stream_id; - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - stream_id= _php_get_stream_index(ffmovie_ctx->fmt_ctx, CODEC_TYPE_AUDIO); - - if( stream_id == -1 ) - { - RETURN_NULL(); - } - else - { - RETURN_LONG(stream_id); - } -} -/* }}} */ - -/* {{{ _php_get_audio_channels() - */ -static int _php_get_codec_channels(ff_movie_context *ffmovie_ctx, int type) -{ - AVCodecContext *decoder_ctx = NULL; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, type); - if (!decoder_ctx) { - return 0; - } - - return decoder_ctx->channels; -} -/* }}} */ - - -/* {{{ proto int getAudioChannels() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioChannels) -{ - ff_movie_context *ffmovie_ctx; - int channels; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - channels = _php_get_codec_channels(ffmovie_ctx, CODEC_TYPE_AUDIO); - - if (channels) { - RETURN_LONG(channels); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ _php_get_codec_sample_rate() - */ -static int _php_get_codec_sample_rate(ff_movie_context *ffmovie_ctx, int type) -{ - AVCodecContext *decoder_ctx = NULL; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, type); - if (!decoder_ctx) { - return 0; - } - - return decoder_ctx->sample_rate; -} -/* }}} */ - - -/* {{{ proto int getAudioSampleRate() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioSampleRate) -{ - ff_movie_context *ffmovie_ctx = NULL; - int sample_rate = 0; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - sample_rate = _php_get_codec_sample_rate(ffmovie_ctx, CODEC_TYPE_AUDIO); - - if (sample_rate) { - RETURN_LONG(sample_rate); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ _php_get_codec_bit_rate() - Returns the bit rate for codec of type. - */ -static int _php_get_codec_bit_rate(ff_movie_context *ffmovie_ctx, int type) -{ - AVCodecContext *decoder_ctx = NULL; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, type); - if (!decoder_ctx) { - return 0; - } - - return decoder_ctx->bit_rate; -} - - -/* {{{ proto int getAudioBitRate() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioBitRate) -{ - ff_movie_context *ffmovie_ctx = NULL; - int bit_rate = 0; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - bit_rate = _php_get_codec_bit_rate(ffmovie_ctx, CODEC_TYPE_AUDIO); - - if (bit_rate) { - RETURN_LONG(bit_rate); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ proto int getVideoBitRate() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getVideoBitRate) -{ - ff_movie_context *ffmovie_ctx = NULL; - int bit_rate = 0; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - bit_rate = _php_get_codec_bit_rate(ffmovie_ctx, CODEC_TYPE_VIDEO); - - if (bit_rate) { - RETURN_LONG(bit_rate); - } else { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ _php_read_av_frame() - Returns the next frame from the movie - */ -static AVFrame* _php_read_av_frame(ff_movie_context *ffmovie_ctx, - AVCodecContext *decoder_ctx, int *is_keyframe, int64_t *pts) -{ - int video_stream; - AVPacket packet; - AVFrame *frame = NULL; - int got_frame; - - video_stream = _php_get_stream_index(ffmovie_ctx->fmt_ctx, - CODEC_TYPE_VIDEO); - if (video_stream < 0) { - return NULL; - } - - frame = avcodec_alloc_frame(); - - /* read next frame */ - while (av_read_frame(ffmovie_ctx->fmt_ctx, &packet) >= 0) { - if (packet.stream_index == video_stream) { - - avcodec_decode_video(decoder_ctx, frame, &got_frame, - packet.data, packet.size); - - if (got_frame) { - *is_keyframe = (packet.flags & PKT_FLAG_KEY); - *pts = packet.pts; - av_free_packet(&packet); - return frame; - } - } - - /* free the packet allocated by av_read_frame */ - av_free_packet(&packet); - } - - av_free(frame); - return NULL; -} -/* }}} */ - -/* {{{ _php_get_av_frame() - Returns a frame from the movie. - */ -#define GETFRAME_KEYFRAME -1 -#define GETFRAME_NEXTFRAME 0 -static AVFrame* _php_get_av_frame(ff_movie_context *ffmovie_ctx, - int wanted_frame, int *is_keyframe, int64_t *pts) -{ - AVCodecContext *decoder_ctx = NULL; - AVFrame *frame = NULL; - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, CODEC_TYPE_VIDEO); - if (decoder_ctx == NULL) { - return NULL; - } - - /* Rewind to the beginning of the stream if wanted frame already passed */ - if (wanted_frame > 0 && wanted_frame <= ffmovie_ctx->frame_number) { - if ( - -#if LIBAVFORMAT_BUILD >= 4619 - av_seek_frame(ffmovie_ctx->fmt_ctx, -1, 0, 0) -#else - av_seek_frame(ffmovie_ctx->fmt_ctx, -1, 0) -#endif - < 0) { - //zend_error(E_ERROR,"Error seeking to beginning of video stream"); - // If we can't seek, fall back to reopening the file. - // NOTE: This may mask locking problems in persistent movies. - _php_open_movie_file(ffmovie_ctx, _php_get_filename(ffmovie_ctx)); - } - - /* flush decoder buffers here */ - avcodec_flush_buffers(decoder_ctx); - - ffmovie_ctx->frame_number = 0; - } - - /* read frames looking for wanted_frame */ - while (1) { - frame = _php_read_av_frame(ffmovie_ctx, decoder_ctx, is_keyframe, pts); - - /* hurry up if we're still a ways from the target frame */ - if (wanted_frame != GETFRAME_KEYFRAME && - wanted_frame != GETFRAME_NEXTFRAME && - wanted_frame - ffmovie_ctx->frame_number > - decoder_ctx->gop_size + 1) { - decoder_ctx->hurry_up = 1; - } else { - decoder_ctx->hurry_up = 0; - } - ffmovie_ctx->frame_number++; - - /* - * if caller wants next keyframe then get it and break out of loop. - */ - if (wanted_frame == GETFRAME_KEYFRAME && is_keyframe) { - return frame; - } - - if (wanted_frame == GETFRAME_NEXTFRAME || - ffmovie_ctx->frame_number == wanted_frame) { - return frame; - } - } - - av_free(frame); - return NULL; -} -/* }}} */ - - -/* {{{ _php_get_ff_frame() - puts a ff_frame object into the php return_value variable - returns 1 on success, 0 on failure. - */ -static int _php_get_ff_frame(ff_movie_context *ffmovie_ctx, - int wanted_frame, INTERNAL_FUNCTION_PARAMETERS) { - int is_keyframe = 0; - int64_t pts; - AVFrame *frame = NULL; - ff_frame_context *ff_frame; - - frame = _php_get_av_frame(ffmovie_ctx, wanted_frame, &is_keyframe, &pts); - if (frame) { - /* - * _php_create_ffmpeg_frame sets PHP return_value to a ffmpeg_frame - * object via INTERNAL_FUNCTION_PARAM_PASSTHRU, the returned ff_frame - * is just for conveniently setting its fields. - */ - ff_frame = _php_create_ffmpeg_frame(INTERNAL_FUNCTION_PARAM_PASSTHRU); - - if (!ff_frame) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Error allocating ffmpeg_frame resource"); - } - - /* TODO: Provide function(s) for setting these in ffmpeg_frame */ - ff_frame->width = _php_get_framewidth(ffmovie_ctx); - ff_frame->height = _php_get_frameheight(ffmovie_ctx); - ff_frame->pixel_format = _php_get_pixelformat(ffmovie_ctx); - ff_frame->keyframe = is_keyframe; - ff_frame->pts = pts; - - ff_frame->av_frame = avcodec_alloc_frame(); - avpicture_alloc((AVPicture*)ff_frame->av_frame, ff_frame->pixel_format, - ff_frame->width, ff_frame->height); - - /* FIXME: temporary hack until I figure out how to pass new buffers - * to the decoder - */ - av_picture_copy((AVPicture*)ff_frame->av_frame, - (AVPicture*)frame, ff_frame->pixel_format, - ff_frame->width, ff_frame->height); - - return 1; - } else { - return 0; - } - -} -/* }}} */ - - -/* {{{ proto resource getNextKeyFrame() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getNextKeyFrame) -{ - ff_movie_context *ffmovie_ctx; - - if (ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - if (!_php_get_ff_frame(ffmovie_ctx, GETFRAME_KEYFRAME, - INTERNAL_FUNCTION_PARAM_PASSTHRU)) { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ proto resource getFrame([int frame]) - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrame) -{ - zval **argv[1]; - int wanted_frame = 0; - ff_movie_context *ffmovie_ctx; - - if (ZEND_NUM_ARGS() > 1) { - WRONG_PARAM_COUNT; - } - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - if (ZEND_NUM_ARGS()) { - - /* retrieve arguments */ - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), argv) != SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Error parsing arguments"); - } - - convert_to_long_ex(argv[0]); - wanted_frame = Z_LVAL_PP(argv[0]); - - /* bounds check wanted frame */ - if (wanted_frame < 1) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, - "Frame number must be greater than zero"); - } - } - - if (! _php_get_ff_frame(ffmovie_ctx, wanted_frame, - INTERNAL_FUNCTION_PARAM_PASSTHRU)) { - RETURN_FALSE; - } -} -/* }}} */ - - -/* {{{ _php_pre_read_frame() - * ffmpeg seems not to fill in some AVCodecContext fields until at least - * one frame is read. This function will read a frame without moving the - * frame counter. - */ -void _php_pre_read_frame(ff_movie_context *ffmovie_ctx) { - AVFrame *frame = NULL; - int is_keyframe; - int64_t pts; - - frame = _php_get_av_frame(ffmovie_ctx, - _php_get_framenumber(ffmovie_ctx) - 1, &is_keyframe, &pts); - - av_free(frame); -} - - -/* {{{ _php_get_sample_aspec_ratio() - */ -static double _php_get_sample_aspect_ratio(ff_movie_context *ffmovie_ctx) -{ - AVCodecContext *decoder_ctx; - - - decoder_ctx = _php_get_decoder_context(ffmovie_ctx, CODEC_TYPE_VIDEO); - if (!decoder_ctx) { - return -1; - } - - - if (decoder_ctx->sample_aspect_ratio.num == 0) { - // pre read a frame so ffmpeg will fill in sample aspect ratio field. - _php_pre_read_frame(ffmovie_ctx); - - if (decoder_ctx->sample_aspect_ratio.num == 0) { - return -2; // aspect not set - } - } - - return av_q2d(decoder_ctx->sample_aspect_ratio); -} -/* }}} */ - - -/* {{{ proto double getPixelAspectRatio() - */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getPixelAspectRatio) -{ - double aspect; - ff_movie_context *ffmovie_ctx; - - GET_MOVIE_RESOURCE(ffmovie_ctx); - - aspect = _php_get_sample_aspect_ratio(ffmovie_ctx); - - if (aspect < 0) { - RETURN_FALSE; - } - - RETURN_DOUBLE(aspect); -} -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_movie.h b/ffmpeg-php/ffmpeg_movie.h deleted file mode 100644 index 38586a7..0000000 --- a/ffmpeg-php/ffmpeg_movie.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#ifndef FFMPEG_MOVIE_H -#define FFMPEG_MOVIE_H - -/* movie constructor */ -FFMPEG_PHP_CONSTRUCTOR(ffmpeg_movie, __construct); - -/* movie methods */ -FFMPEG_PHP_METHOD(ffmpeg_movie, getDuration); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameCount); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameRate); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFileName); -FFMPEG_PHP_METHOD(ffmpeg_movie, getComment); -FFMPEG_PHP_METHOD(ffmpeg_movie, getTitle); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAuthor); -FFMPEG_PHP_METHOD(ffmpeg_movie, getCopyright); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAlbum); -FFMPEG_PHP_METHOD(ffmpeg_movie, getGenre); -FFMPEG_PHP_METHOD(ffmpeg_movie, getTrackNumber); -FFMPEG_PHP_METHOD(ffmpeg_movie, getYear); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameWidth); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameHeight); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrameNumber); -FFMPEG_PHP_METHOD(ffmpeg_movie, getPixelFormat); -FFMPEG_PHP_METHOD(ffmpeg_movie, getBitRate); -FFMPEG_PHP_METHOD(ffmpeg_movie, hasAudio); -FFMPEG_PHP_METHOD(ffmpeg_movie, hasVideo); -FFMPEG_PHP_METHOD(ffmpeg_movie, getNextKeyFrame); -FFMPEG_PHP_METHOD(ffmpeg_movie, getFrame); -FFMPEG_PHP_METHOD(ffmpeg_movie, getVideoCodec); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioCodec); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioChannels); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioSampleRate); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioBitRate); -FFMPEG_PHP_METHOD(ffmpeg_movie, getVideoBitRate); -FFMPEG_PHP_METHOD(ffmpeg_movie, getPixelAspectRatio); -FFMPEG_PHP_METHOD(ffmpeg_movie, getVideoStreamId); -FFMPEG_PHP_METHOD(ffmpeg_movie, getAudioStreamId); - -#endif // FFMPEG_MOVIE_H - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_tools.c b/ffmpeg-php/ffmpeg_tools.c deleted file mode 100644 index 75e11df..0000000 --- a/ffmpeg-php/ffmpeg_tools.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "ffmpeg_tools.h" - -#ifdef HAVE_SWSCALER -#include -#endif - -/* {{{ ffmpeg_img_convert() - * wrapper around ffmpeg image conversion routines - */ -int ffmpeg_img_convert(AVPicture *dst, int dst_pix_fmt, - AVPicture *src, int src_pix_fmt, - int src_width, int src_height) -{ -#ifndef HAVE_SWSCALER // No SWSCALER so just use img_convert - return img_convert(dst, dst_pix_fmt, - src, src_pix_fmt, src_width, src_height); -#else // Do swscale convert - int result = 0; - struct SwsContext *sws_ctx = NULL; - - if (src_pix_fmt == dst_pix_fmt) { - return 0; - } - - // TODO: Try to get cached sws_context first - sws_ctx = sws_getContext( - src_width, src_height, src_pix_fmt, - src_width, src_height, dst_pix_fmt, - SWS_BICUBIC, NULL, NULL, NULL); - - if (sws_ctx == NULL){ - return 1; - } - - result = sws_scale(sws_ctx, - src->data, src->linesize, - 0, src_height, - dst->data, dst->linesize); - - sws_freeContext(sws_ctx); - - if (result == 0){ - return 2; - } -#endif // NOT HAVE_SWSCALER - return 0; -} -/* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/ffmpeg_tools.h b/ffmpeg-php/ffmpeg_tools.h deleted file mode 100644 index 5da2b6c..0000000 --- a/ffmpeg-php/ffmpeg_tools.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#ifndef FFMPEG_TOOLS_H -#define FFMPEG_TOOLS_H - -#include - -int ffmpeg_img_convert( - AVPicture *dst, int dst_pix_fmt, - AVPicture *src, int src_pix_fmt, - int src_width, int src_height); - -#endif // FFMPEG_TOOLS_H - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 - * vim<600: noet sw=4 ts=4 - */ diff --git a/ffmpeg-php/gd.h b/ffmpeg-php/gd.h deleted file mode 100644 index 7ef2caa..0000000 --- a/ffmpeg-php/gd.h +++ /dev/null @@ -1,686 +0,0 @@ -#ifndef GD_H -#define GD_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php_compat.h" - -#define GD_MAJOR_VERSION 2 -#define GD_MINOR_VERSION 0 -#define GD_RELEASE_VERSION 35 -#define GD_EXTRA_VERSION "" -#define GD_VERSION_STRING "2.0.35" - -#ifdef NETWARE -/* default fontpath for netware systems */ -#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;." -#define PATHSEPARATOR ";" -#elif defined(WIN32) -/* default fontpath for windows systems */ -#define DEFAULT_FONTPATH "c:\\winnt\\fonts;c:\\windows\\fonts;." -#define PATHSEPARATOR ";" -#else -/* default fontpath for unix systems */ -#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:." -#define PATHSEPARATOR ":" -#endif - -/* gd.h: declarations file for the graphic-draw module. - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. This software is provided "AS IS." Thomas Boutell and - * Boutell.Com, Inc. disclaim all warranties, either express or implied, - * including but not limited to implied warranties of merchantability and - * fitness for a particular purpose, with respect to this code and accompanying - * documentation. */ - -/* stdio is needed for file I/O. */ -#include -#include "gd_io.h" - -void php_gd_error_ex(int type, const char *format, ...); - -void php_gd_error(const char *format, ...); - - -/* The maximum number of palette entries in palette-based images. - In the wonderful new world of gd 2.0, you can of course have - many more colors when using truecolor mode. */ - -#define gdMaxColors 256 - -/* Image type. See functions below; you will not need to change - the elements directly. Use the provided macros to - access sx, sy, the color table, and colorsTotal for - read-only purposes. */ - -/* If 'truecolor' is set true, the image is truecolor; - pixels are represented by integers, which - must be 32 bits wide or more. - - True colors are repsented as follows: - - ARGB - - Where 'A' (alpha channel) occupies only the - LOWER 7 BITS of the MSB. This very small - loss of alpha channel resolution allows gd 2.x - to keep backwards compatibility by allowing - signed integers to be used to represent colors, - and negative numbers to represent special cases, - just as in gd 1.x. */ - -#define gdAlphaMax 127 -#define gdAlphaOpaque 0 -#define gdAlphaTransparent 127 -#define gdRedMax 255 -#define gdGreenMax 255 -#define gdBlueMax 255 -#define gdTrueColorGetAlpha(c) (((c) & 0x7F000000) >> 24) -#define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16) -#define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8) -#define gdTrueColorGetBlue(c) ((c) & 0x0000FF) -#define gdEffectReplace 0 -#define gdEffectAlphaBlend 1 -#define gdEffectNormal 2 -#define gdEffectOverlay 3 - - -/* This function accepts truecolor pixel values only. The - source color is composited with the destination color - based on the alpha channel value of the source color. - The resulting color is opaque. */ - -int gdAlphaBlend(int dest, int src); - -typedef struct gdImageStruct { - /* Palette-based image pixels */ - unsigned char ** pixels; - int sx; - int sy; - /* These are valid in palette images only. See also - 'alpha', which appears later in the structure to - preserve binary backwards compatibility */ - int colorsTotal; - int red[gdMaxColors]; - int green[gdMaxColors]; - int blue[gdMaxColors]; - int open[gdMaxColors]; - /* For backwards compatibility, this is set to the - first palette entry with 100% transparency, - and is also set and reset by the - gdImageColorTransparent function. Newer - applications can allocate palette entries - with any desired level of transparency; however, - bear in mind that many viewers, notably - many web browsers, fail to implement - full alpha channel for PNG and provide - support for full opacity or transparency only. */ - int transparent; - int *polyInts; - int polyAllocated; - struct gdImageStruct *brush; - struct gdImageStruct *tile; - int brushColorMap[gdMaxColors]; - int tileColorMap[gdMaxColors]; - int styleLength; - int stylePos; - int *style; - int interlace; - /* New in 2.0: thickness of line. Initialized to 1. */ - int thick; - /* New in 2.0: alpha channel for palettes. Note that only - Macintosh Internet Explorer and (possibly) Netscape 6 - really support multiple levels of transparency in - palettes, to my knowledge, as of 2/15/01. Most - common browsers will display 100% opaque and - 100% transparent correctly, and do something - unpredictable and/or undesirable for levels - in between. TBB */ - int alpha[gdMaxColors]; - /* Truecolor flag and pixels. New 2.0 fields appear here at the - end to minimize breakage of existing object code. */ - int trueColor; - int ** tpixels; - /* Should alpha channel be copied, or applied, each time a - pixel is drawn? This applies to truecolor images only. - No attempt is made to alpha-blend in palette images, - even if semitransparent palette entries exist. - To do that, build your image as a truecolor image, - then quantize down to 8 bits. */ - int alphaBlendingFlag; - /* Should antialias functions be used */ - int antialias; - /* Should the alpha channel of the image be saved? This affects - PNG at the moment; other future formats may also - have that capability. JPEG doesn't. */ - int saveAlphaFlag; - - - /* 2.0.12: anti-aliased globals */ - int AA; - int AA_color; - int AA_dont_blend; - unsigned char **AA_opacity; - int AA_polygon; - /* Stored and pre-computed variables for determining the perpendicular - * distance from a point to the anti-aliased line being drawn: - */ - int AAL_x1; - int AAL_y1; - int AAL_x2; - int AAL_y2; - int AAL_Bx_Ax; - int AAL_By_Ay; - int AAL_LAB_2; - float AAL_LAB; - - /* 2.0.12: simple clipping rectangle. These values must be checked for safety when set; please use gdImageSetClip */ - int cx1; - int cy1; - int cx2; - int cy2; -} gdImage; - -typedef gdImage * gdImagePtr; - -typedef struct { - /* # of characters in font */ - int nchars; - /* First character is numbered... (usually 32 = space) */ - int offset; - /* Character width and height */ - int w; - int h; - /* Font data; array of characters, one row after another. - Easily included in code, also easily loaded from - data files. */ - char *data; -} gdFont; - -/* Text functions take these. */ -typedef gdFont *gdFontPtr; - -/* For backwards compatibility only. Use gdImageSetStyle() - for MUCH more flexible line drawing. Also see - gdImageSetBrush(). */ -#define gdDashSize 4 - -/* Special colors. */ - -#define gdStyled (-2) -#define gdBrushed (-3) -#define gdStyledBrushed (-4) -#define gdTiled (-5) - -/* NOT the same as the transparent color index. - This is used in line styles only. */ -#define gdTransparent (-6) - -#define gdAntiAliased (-7) - -/* Functions to manipulate images. */ - -/* Creates a palette-based image (up to 256 colors). */ -gdImagePtr gdImageCreate(int sx, int sy); - -/* An alternate name for the above (2.0). */ -#define gdImageCreatePalette gdImageCreate - -/* Creates a truecolor image (millions of colors). */ -gdImagePtr gdImageCreateTrueColor(int sx, int sy); - -/* Creates an image from various file types. These functions - return a palette or truecolor image based on the - nature of the file being loaded. Truecolor PNG - stays truecolor; palette PNG stays palette-based; - JPEG is always truecolor. */ -gdImagePtr gdImageCreateFromPng(FILE *fd); -gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in); -gdImagePtr gdImageCreateFromWBMP(FILE *inFile); -gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile); -gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning); -gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning); - -/* A custom data source. */ -/* The source function must return -1 on error, otherwise the number - of bytes fetched. 0 is EOF, not an error! */ -/* context will be passed to your source function. */ - -typedef struct { - int (*source) (void *context, char *buffer, int len); - void *context; -} gdSource, *gdSourcePtr; - -gdImagePtr gdImageCreateFromPngSource(gdSourcePtr in); - -gdImagePtr gdImageCreateFromGd(FILE *in); -gdImagePtr gdImageCreateFromGdCtx(gdIOCtxPtr in); - -gdImagePtr gdImageCreateFromGd2(FILE *in); -gdImagePtr gdImageCreateFromGd2Ctx(gdIOCtxPtr in); - -gdImagePtr gdImageCreateFromGd2Part(FILE *in, int srcx, int srcy, int w, int h); -gdImagePtr gdImageCreateFromGd2PartCtx(gdIOCtxPtr in, int srcx, int srcy, int w, int h); - -gdImagePtr gdImageCreateFromXbm(FILE *fd); -void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out); - -gdImagePtr gdImageCreateFromXpm (char *filename); - -void gdImageDestroy(gdImagePtr im); - -/* Replaces or blends with the background depending on the - most recent call to gdImageAlphaBlending and the - alpha channel value of 'color'; default is to overwrite. - Tiling and line styling are also implemented - here. All other gd drawing functions pass through this call, - allowing for many useful effects. */ - -void gdImageSetPixel(gdImagePtr im, int x, int y, int color); - -int gdImageGetPixel(gdImagePtr im, int x, int y); - -void gdImageAABlend(gdImagePtr im); - -void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -void gdImageAALine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); - -/* For backwards compatibility only. Use gdImageSetStyle() - for much more flexible line drawing. */ -void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -/* Corners specified (not width and height). Upper left first, lower right - second. */ -void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -/* Solid bar. Upper left corner first, lower right corner second. */ -void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2); -void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P); -void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); -void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); -void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); -void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); -void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); -void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); - -/* - * The following functions are required to be called prior to the - * use of any sort of threads in a module load / shutdown function - * respectively. - */ -void gdFontCacheMutexSetup(); -void gdFontCacheMutexShutdown(); - -/* 2.0.16: for thread-safe use of gdImageStringFT and friends, - * call this before allowing any thread to call gdImageStringFT. - * Otherwise it is invoked by the first thread to invoke - * gdImageStringFT, with a very small but real risk of a race condition. - * Return 0 on success, nonzero on failure to initialize freetype. - */ -int gdFontCacheSetup(void); - -/* Optional: clean up after application is done using fonts in gdImageStringFT(). */ -void gdFontCacheShutdown(void); - -/* Calls gdImageStringFT. Provided for backwards compatibility only. */ -char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string); - -/* FreeType 2 text output */ -char *gdImageStringFT(gdImage *im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string); - -typedef struct { - double linespacing; /* fine tune line spacing for '\n' */ - int flags; /* Logical OR of gdFTEX_ values */ - int charmap; /* TBB: 2.0.12: may be gdFTEX_Unicode, - gdFTEX_Shift_JIS, or gdFTEX_Big5; - when not specified, maps are searched - for in the above order. */ - int hdpi; - int vdpi; -} - gdFTStringExtra, *gdFTStringExtraPtr; - -#define gdFTEX_LINESPACE 1 -#define gdFTEX_CHARMAP 2 -#define gdFTEX_RESOLUTION 4 - -/* These are NOT flags; set one in 'charmap' if you set the gdFTEX_CHARMAP bit in 'flags'. */ -#define gdFTEX_Unicode 0 -#define gdFTEX_Shift_JIS 1 -#define gdFTEX_Big5 2 - -/* FreeType 2 text output with fine tuning */ -char * -gdImageStringFTEx(gdImage * im, int *brect, int fg, char * fontlist, - double ptsize, double angle, int x, int y, char * string, - gdFTStringExtraPtr strex); - - -/* Point type for use in polygon drawing. */ -typedef struct { - int x, y; -} gdPoint, *gdPointPtr; - -void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c); -void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c); - -/* These functions still work with truecolor images, - for which they never return error. */ -int gdImageColorAllocate(gdImagePtr im, int r, int g, int b); -/* gd 2.0: palette entries with non-opaque transparency are permitted. */ -int gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a); -/* Assumes opaque is the preferred alpha channel value */ -int gdImageColorClosest(gdImagePtr im, int r, int g, int b); -/* Closest match taking all four parameters into account. - A slightly different color with the same transparency - beats the exact same color with radically different - transparency */ -int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a); -/* An alternate method */ -int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b); -/* Returns exact, 100% opaque matches only */ -int gdImageColorExact(gdImagePtr im, int r, int g, int b); -/* Returns an exact match only, including alpha */ -int gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a); -/* Opaque only */ -int gdImageColorResolve(gdImagePtr im, int r, int g, int b); -/* Based on gdImageColorExactAlpha and gdImageColorClosestAlpha */ -int gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a); - -/* A simpler way to obtain an opaque truecolor value for drawing on a - truecolor image. Not for use with palette images! */ - -#define gdTrueColor(r, g, b) (((r) << 16) + \ - ((g) << 8) + \ - (b)) - -/* Returns a truecolor value with an alpha channel component. - gdAlphaMax (127, **NOT 255**) is transparent, 0 is completely - opaque. */ - -#define gdTrueColorAlpha(r, g, b, a) (((a) << 24) + \ - ((r) << 16) + \ - ((g) << 8) + \ - (b)) - -void gdImageColorDeallocate(gdImagePtr im, int color); - -/* Converts a truecolor image to a palette-based image, - using a high-quality two-pass quantization routine - which attempts to preserve alpha channel information - as well as R/G/B color information when creating - a palette. If ditherFlag is set, the image will be - dithered to approximate colors better, at the expense - of some obvious "speckling." colorsWanted can be - anything up to 256. If the original source image - includes photographic information or anything that - came out of a JPEG, 256 is strongly recommended. - - Better yet, don't use this function -- write real - truecolor PNGs and JPEGs. The disk space gain of - conversion to palette is not great (for small images - it can be negative) and the quality loss is ugly. */ - -gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int ditherFlag, int colorsWanted); - -void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted); - - -/* An attempt at getting the results of gdImageTrueColorToPalette - to look a bit more like the original (im1 is the original - and im2 is the palette version */ -int gdImageColorMatch(gdImagePtr im1, gdImagePtr im2); - -/* Specifies a color index (if a palette image) or an - RGB color (if a truecolor image) which should be - considered 100% transparent. FOR TRUECOLOR IMAGES, - THIS IS IGNORED IF AN ALPHA CHANNEL IS BEING - SAVED. Use gdImageSaveAlpha(im, 0); to - turn off the saving of a full alpha channel in - a truecolor image. Note that gdImageColorTransparent - is usually compatible with older browsers that - do not understand full alpha channels well. TBB */ -void gdImageColorTransparent(gdImagePtr im, int color); - -void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src); -void gdImagePng(gdImagePtr im, FILE *out); -void gdImagePngCtx(gdImagePtr im, gdIOCtx *out); -void gdImageGif(gdImagePtr im, FILE *out); -void gdImageGifCtx(gdImagePtr im, gdIOCtx *out); -/* 2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all, - * 1 is FASTEST but produces larger files, 9 provides the best - * compression (smallest files) but takes a long time to compress, and - * -1 selects the default compiled into the zlib library. - */ -void gdImagePngEx(gdImagePtr im, FILE * out, int level, int basefilter); -void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level, int basefilter); - -void gdImageWBMP(gdImagePtr image, int fg, FILE *out); -void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); - -/* Guaranteed to correctly free memory returned - by the gdImage*Ptr functions */ -void gdFree(void *m); - -/* Best to free this memory with gdFree(), not free() */ -void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg); - -/* 100 is highest quality (there is always a little loss with JPEG). - 0 is lowest. 10 is about the lowest useful setting. */ -void gdImageJpeg(gdImagePtr im, FILE *out, int quality); -void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); - -/* Best to free this memory with gdFree(), not free() */ -void *gdImageJpegPtr(gdImagePtr im, int *size, int quality); - -gdImagePtr gdImageCreateFromGif(FILE *fd); -gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr in); -gdImagePtr gdImageCreateFromGifSource(gdSourcePtr in); - -/* A custom data sink. For backwards compatibility. Use - gdIOCtx instead. */ -/* The sink function must return -1 on error, otherwise the number - of bytes written, which must be equal to len. */ -/* context will be passed to your sink function. */ -typedef struct { - int (*sink) (void *context, const char *buffer, int len); - void *context; -} gdSink, *gdSinkPtr; - -void gdImagePngToSink(gdImagePtr im, gdSinkPtr out); - -void gdImageGd(gdImagePtr im, FILE *out); -void gdImageGd2(gdImagePtr im, FILE *out, int cs, int fmt); - -/* Best to free this memory with gdFree(), not free() */ -void* gdImagePngPtr(gdImagePtr im, int *size); - -/* Best to free this memory with gdFree(), not free() */ -void* gdImageGdPtr(gdImagePtr im, int *size); -void *gdImagePngPtrEx(gdImagePtr im, int *size, int level, int basefilter); - -/* Best to free this memory with gdFree(), not free() */ -void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size); - -void gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int c); - -/* Style is a bitwise OR ( | operator ) of these. - gdArc and gdChord are mutually exclusive; - gdChord just connects the starting and ending - angles with a straight line, while gdArc produces - a rounded edge. gdPie is a synonym for gdArc. - gdNoFill indicates that the arc or chord should be - outlined, not filled. gdEdged, used together with - gdNoFill, indicates that the beginning and ending - angles should be connected to the center; this is - a good way to outline (rather than fill) a - 'pie slice'. */ -#define gdArc 0 -#define gdPie gdArc -#define gdChord 1 -#define gdNoFill 2 -#define gdEdged 4 - -void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style); -void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color); -void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color); -void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color); -void gdImageFill(gdImagePtr im, int x, int y, int color); -void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h); -void gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, - int srcX, int srcY, int w, int h, int pct); -void gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, - int srcX, int srcY, int w, int h, int pct); - -/* Stretches or shrinks to fit, as needed. Does NOT attempt - to average the entire set of source pixels that scale down onto the - destination pixel. */ -void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH); - -/* gd 2.0: stretches or shrinks to fit, as needed. When called with a - truecolor destination image, this function averages the - entire set of source pixels that scale down onto the - destination pixel, taking into account what portion of the - destination pixel each source pixel represents. This is a - floating point operation, but this is not a performance issue - on modern hardware, except for some embedded devices. If the - destination is a palette image, gdImageCopyResized is - substituted automatically. */ -void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH); - -gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent); -gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent); -gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent); -gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent); -gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent); - -void gdImageSetBrush(gdImagePtr im, gdImagePtr brush); -void gdImageSetTile(gdImagePtr im, gdImagePtr tile); -void gdImageSetAntiAliased(gdImagePtr im, int c); -void gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c, int dont_blend); -void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels); -/* Line thickness (defaults to 1). Affects lines, ellipses, - rectangles, polygons and so forth. */ -void gdImageSetThickness(gdImagePtr im, int thickness); -/* On or off (1 or 0) for all three of these. */ -void gdImageInterlace(gdImagePtr im, int interlaceArg); -void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg); -void gdImageAntialias(gdImagePtr im, int antialias); -void gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg); - -/* Macros to access information about images. */ - -/* Returns nonzero if the image is a truecolor image, - zero for a palette image. */ - -#define gdImageTrueColor(im) ((im)->trueColor) - -#define gdImageSX(im) ((im)->sx) -#define gdImageSY(im) ((im)->sy) -#define gdImageColorsTotal(im) ((im)->colorsTotal) -#define gdImageRed(im, c) ((im)->trueColor ? gdTrueColorGetRed(c) : \ - (im)->red[(c)]) -#define gdImageGreen(im, c) ((im)->trueColor ? gdTrueColorGetGreen(c) : \ - (im)->green[(c)]) -#define gdImageBlue(im, c) ((im)->trueColor ? gdTrueColorGetBlue(c) : \ - (im)->blue[(c)]) -#define gdImageAlpha(im, c) ((im)->trueColor ? gdTrueColorGetAlpha(c) : \ - (im)->alpha[(c)]) -#define gdImageGetTransparent(im) ((im)->transparent) -#define gdImageGetInterlaced(im) ((im)->interlace) - -/* These macros provide direct access to pixels in - palette-based and truecolor images, respectively. - If you use these macros, you must perform your own - bounds checking. Use of the macro for the correct type - of image is also your responsibility. */ -#define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)] -#define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)] - -/* I/O Support routines. */ - -gdIOCtx* gdNewFileCtx(FILE*); -gdIOCtx* gdNewDynamicCtx(int, void*); -gdIOCtx *gdNewDynamicCtxEx(int size, void *data, int freeFlag); -gdIOCtx* gdNewSSCtx(gdSourcePtr in, gdSinkPtr out); -void* gdDPExtractData(struct gdIOCtx* ctx, int *size); - -#define GD2_CHUNKSIZE 128 -#define GD2_CHUNKSIZE_MIN 64 -#define GD2_CHUNKSIZE_MAX 4096 - -#define GD2_VERS 2 -#define GD2_ID "gd2" -#define GD2_FMT_RAW 1 -#define GD2_FMT_COMPRESSED 2 - - -/* filters section - * - * Negate the imag src, white becomes black, - * The red, green, and blue intensities of an image are negated. - * White becomes black, yellow becomes blue, etc. - */ -int gdImageNegate(gdImagePtr src); - -/* Convert the image src to a grayscale image */ -int gdImageGrayScale(gdImagePtr src); - -/* Set the brightness level for the image src */ -int gdImageBrightness(gdImagePtr src, int brightness); - -/* Set the contrast level for the image */ -int gdImageContrast(gdImagePtr src, double contrast); - -/* Simply adds or substracts respectively red, green or blue to a pixel */ -int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha); - -/* Image convolution by a 3x3 custom matrix */ -int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float offset); - -int gdImageEdgeDetectQuick(gdImagePtr src); - -int gdImageGaussianBlur(gdImagePtr im); - -int gdImageSelectiveBlur( gdImagePtr src); - -int gdImageEmboss(gdImagePtr im); - -int gdImageMeanRemoval(gdImagePtr im); - -int gdImageSmooth(gdImagePtr im, float weight); - -/* Image comparison definitions */ -int gdImageCompare(gdImagePtr im1, gdImagePtr im2); - -#define GD_CMP_IMAGE 1 /* Actual image IS different */ -#define GD_CMP_NUM_COLORS 2 /* Number of Colours in pallette differ */ -#define GD_CMP_COLOR 4 /* Image colours differ */ -#define GD_CMP_SIZE_X 8 /* Image width differs */ -#define GD_CMP_SIZE_Y 16 /* Image heights differ */ -#define GD_CMP_TRANSPARENT 32 /* Transparent colour */ -#define GD_CMP_BACKGROUND 64 /* Background colour */ -#define GD_CMP_INTERLACE 128 /* Interlaced setting */ -#define GD_CMP_TRUECOLOR 256 /* Truecolor vs palette differs */ - -/* resolution affects ttf font rendering, particularly hinting */ -#define GD_RESOLUTION 96 /* pixels per inch */ - -#ifdef __cplusplus -} -#endif - -/* 2.0.12: this now checks the clipping rectangle */ -#define gdImageBoundsSafe(im, x, y) (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2)))) - -#endif /* GD_H */ diff --git a/ffmpeg-php/gd_io.h b/ffmpeg-php/gd_io.h deleted file mode 100644 index b893751..0000000 --- a/ffmpeg-php/gd_io.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef GD_IO_H -#define GD_IO_H 1 - -#include - -#ifdef VMS -#define Putchar gdPutchar -#endif - -typedef struct gdIOCtx { - int (*getC)(struct gdIOCtx*); - int (*getBuf)(struct gdIOCtx*, void*, int); - - void (*putC)(struct gdIOCtx*, int); - int (*putBuf)(struct gdIOCtx*, const void*, int); - - int (*seek)(struct gdIOCtx*, const int); - long (*tell)(struct gdIOCtx*); - - void (*gd_free)(struct gdIOCtx*); - -} gdIOCtx; - -typedef struct gdIOCtx *gdIOCtxPtr; - -void Putword(int w, gdIOCtx *ctx); -void Putchar(int c, gdIOCtx *ctx); - -void gdPutC(const unsigned char c, gdIOCtx *ctx); -int gdPutBuf(const void *, int, gdIOCtx*); -void gdPutWord(int w, gdIOCtx *ctx); -void gdPutInt(int w, gdIOCtx *ctx); - -int gdGetC(gdIOCtx *ctx); -int gdGetBuf(void *, int, gdIOCtx*); -int gdGetByte(int *result, gdIOCtx *ctx); -int gdGetWord(int *result, gdIOCtx *ctx); -int gdGetInt(int *result, gdIOCtx *ctx); - -int gdSeek(gdIOCtx *ctx, const int); -long gdTell(gdIOCtx *ctx); - -#endif diff --git a/ffmpeg-php/php_ffmpeg.h b/ffmpeg-php/php_ffmpeg.h deleted file mode 100644 index 0214608..0000000 --- a/ffmpeg-php/php_ffmpeg.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - This file is part of ffmpeg-php - - Copyright (C) 2004-2008 Todd Kirby (ffmpeg.php AT gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - In addition, as a special exception, the copyright holders of ffmpeg-php - give you permission to combine ffmpeg-php with code included in the - standard release of PHP under the PHP license (or modified versions of - such code, with unchanged license). You may copy and distribute such a - system following the terms of the GNU GPL for ffmpeg-php and the licenses - of the other code concerned, provided that you include the source code of - that other code when and as the GNU GPL requires distribution of source code. - - You must obey the GNU General Public License in all respects for all of the - code used other than standard release of PHP. If you modify this file, you - may extend this exception to your version of the file, but you are not - obligated to do so. If you do not wish to do so, delete this exception - statement from your version. - - */ - -#ifndef PHP_FFMPEG_H -#define PHP_FFMPEG_H - -#include "php_version.h" - - -/* - * PHP-4 doesn't have the METHOD, ME and MALIAS macros so map them back - * to the function macros for PHP-4 - */ - -#if PHP_MAJOR_VERSION <= 4 // PHP4; use FUNCTION macros -#define FFMPEG_PHP_CONSTRUCTOR(a,b) PHP_FUNCTION(a) -#define FFMPEG_PHP_METHOD(a,b) PHP_FUNCTION(b) -#define FFMPEG_PHP_ME(a,b,c,d) PHP_FE(a,c) -#define FFMPEG_PHP_MALIAS(a,b,c,d,e) PHP_FALIAS(b,c,d) -#define FFMPEG_PHP_END_METHODS {NULL, NULL, NULL} -#else /* PHP5; Use METHOD macros */ -#define FFMPEG_PHP_CONSTRUCTOR(a,b) PHP_METHOD(a,b) -#define FFMPEG_PHP_METHOD(a,b) PHP_METHOD(a,b) -#define FFMPEG_PHP_ME(a,b,c,d) PHP_ME(a,b,c,d) -#define FFMPEG_PHP_MALIAS(a,b,c,d,e) PHP_MALIAS(a,b,c,d,e) -#define FFMPEG_PHP_END_METHODS {NULL, NULL, NULL, 0, 0} -#endif - - - - -#define SAFE_STRING(s) ((s)?(s):"") - -#ifndef safe_emalloc - # define safe_emalloc(a,b,c) emalloc((a)*(b)+(c)) -#endif - -extern zend_module_entry ffmpeg_module_entry; -#define phpext_ffmpeg_ptr &ffmpeg_module_entry - -#ifdef PHP_WIN32 -#define PHP_FFMPEG_API __declspec(dllexport) -#else -#define PHP_FFMPEG_API -#endif - -#ifdef ZTS -#include "TSRM.h" -#endif - -PHP_MINIT_FUNCTION(ffmpeg); -PHP_MSHUTDOWN_FUNCTION(ffmpeg); -PHP_RINIT_FUNCTION(ffmpeg); -PHP_RSHUTDOWN_FUNCTION(ffmpeg); -PHP_MINFO_FUNCTION(ffmpeg); - - -#ifdef ZTS -#define FFMPEG_G(v) TSRMG(ffmpeg_globals_id, zend_ffmpeg_globals *, v) -#else -#define FFMPEG_G(v) (ffmpeg_globals.v) -#endif - -#endif /* PHP_FFMPEG_H */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * indent-tabs-mode: t - * End: - */ diff --git a/ffmpeg-php/run-tests.php b/ffmpeg-php/run-tests.php deleted file mode 100644 index a740264..0000000 --- a/ffmpeg-php/run-tests.php +++ /dev/null @@ -1,2328 +0,0 @@ -#!/usr/bin/php - | - | Preston L. Bannister | - | Marcus Boerger | - | Derick Rethans | - | Sander Roobol | - | (based on version by: Stig Bakken ) | - | (based on the PHP 3 test framework by Rasmus Lerdorf) | - +----------------------------------------------------------------------+ - */ - -/* $Id: run-tests.php,v 1.226.2.37.2.51 2008/12/03 14:27:43 robinf Exp $ */ - -/* Sanity check to ensure that pcre extension needed by this script is available. - * In the event it is not, print a nice error message indicating that this script will - * not run without it. - */ - -if (!extension_loaded('pcre')) { - echo <<'; - save_text($info_file, $php_info); - $info_params = array(); - settings2array($ini_overwrites, $info_params); - settings2params($info_params); - $php_info = `$php $pass_options $info_params "$info_file"`; - define('TESTED_PHP_VERSION', `$php -n -r "echo PHP_VERSION;"`); - - if ($php_cgi && $php != $php_cgi) { - $php_info_cgi = `$php_cgi $pass_options $info_params -q "$info_file"`; - $php_info_sep = "\n---------------------------------------------------------------------"; - $php_cgi_info = "$php_info_sep\nPHP : $php_cgi $php_info_cgi$php_info_sep"; - } else { - $php_cgi_info = ''; - } - - @unlink($info_file); - - // load list of enabled extensions - save_text($info_file, ''); - $exts_to_test = explode(',',`$php $pass_options $info_params "$info_file"`); - // check for extensions that need special handling and regenerate - $info_params_ex = array( - 'session' => array('session.auto_start=0'), - 'tidy' => array('tidy.clean_output=0'), - 'zlib' => array('zlib.output_compression=Off'), - 'xdebug' => array('xdebug.default_enable=0'), - 'mbstring' => array('mbstring.func_overload=0'), - ); - - foreach($info_params_ex as $ext => $ini_overwrites_ex) { - if (in_array($ext, $exts_to_test)) { - $ini_overwrites = array_merge($ini_overwrites, $ini_overwrites_ex); - } - } - - @unlink($info_file); - - // Write test context information. - echo " -===================================================================== -PHP : $php $php_info $php_cgi_info -CWD : $cwd -Extra dirs : "; - foreach ($user_tests as $test_dir) { - echo "{$test_dir}\n "; - } - echo " -VALGRIND : " . ($leak_check ? $valgrind_header : 'Not used') . " -===================================================================== -"; -} - -define('PHP_QA_EMAIL', 'qa-reports@lists.php.net'); -define('QA_SUBMISSION_PAGE', 'http://qa.php.net/buildtest-process.php'); - -function save_or_mail_results() -{ - global $sum_results, $just_save_results, $failed_test_summary, - $PHP_FAILED_TESTS, $CUR_DIR, $php, $output_file, $compression; - - /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */ - if (false) { - $fp = fopen("php://stdin", "r+"); - if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED'] || $sum_results['XFAILED']) { - echo "\nYou may have found a problem in PHP."; - } - echo "\nWe would like to send this report automatically to the\n"; - echo "PHP QA team, to give us a better understanding of how\nthe test cases are doing. If you don't want to send it\n"; - echo "immediately, you can choose \"s\" to save the report to\na file that you can send us later.\n"; - echo "Do you want to send this report now? [Yns]: "; - flush(); - - $user_input = fgets($fp, 10); - $just_save_results = (strtolower($user_input[0]) == 's'); - } - - if ($just_save_results || false) { - if ($just_save_results || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') { - /* - * Collect information about the host system for our report - * Fetch phpinfo() output so that we can see the PHP enviroment - * Make an archive of all the failed tests - * Send an email - */ - if ($just_save_results) { - $user_input = 's'; - } - - /* Ask the user to provide an email address, so that QA team can contact the user */ - if (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) { - echo "\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): "; - flush(); - $user_email = trim(fgets($fp, 1024)); - $user_email = str_replace("@", " at ", str_replace(".", " dot ", $user_email)); - } - - $failed_tests_data = ''; - $sep = "\n" . str_repeat('=', 80) . "\n"; - $failed_tests_data .= $failed_test_summary . "\n"; - $failed_tests_data .= get_summary(true, false) . "\n"; - - if ($sum_results['FAILED']) { - foreach ($PHP_FAILED_TESTS['FAILED'] as $test_info) { - $failed_tests_data .= $sep . $test_info['name'] . $test_info['info']; - $failed_tests_data .= $sep . file_get_contents(realpath($test_info['output'])); - $failed_tests_data .= $sep . file_get_contents(realpath($test_info['diff'])); - $failed_tests_data .= $sep . "\n\n"; - } - $status = "failed"; - } else { - $status = "success"; - } - - $failed_tests_data .= "\n" . $sep . 'BUILD ENVIRONMENT' . $sep; - $failed_tests_data .= "OS:\n" . PHP_OS . " - " . php_uname() . "\n\n"; - $ldd = $autoconf = $sys_libtool = $libtool = $compiler = 'N/A'; - - if (substr(PHP_OS, 0, 3) != "WIN") { - /* If PHP_AUTOCONF is set, use it; otherwise, use 'autoconf'. */ - if (getenv('PHP_AUTOCONF')) { - $autoconf = shell_exec(getenv('PHP_AUTOCONF') . ' --version'); - } else { - $autoconf = shell_exec('autoconf --version'); - } - - /* Always use the generated libtool - Mac OSX uses 'glibtool' */ - $libtool = shell_exec($CUR_DIR . '/libtool --version'); - - /* Use shtool to find out if there is glibtool present (MacOSX) */ - $sys_libtool_path = shell_exec(realpath(dirname(__FILE__)) . '/build/shtool path glibtool libtool'); - - if ($sys_libtool_path) { - $sys_libtool = shell_exec(str_replace("\n", "", $sys_libtool_path) . ' --version'); - } - - /* Try the most common flags for 'version' */ - $flags = array('-v', '-V', '--version'); - $cc_status = 0; - - foreach($flags AS $flag) { - system(getenv('CC') . " $flag >/dev/null 2>&1", $cc_status); - if ($cc_status == 0) { - $compiler = shell_exec(getenv('CC') . " $flag 2>&1"); - break; - } - } - - $ldd = shell_exec("ldd $php 2>/dev/null"); - } - - $failed_tests_data .= "Autoconf:\n$autoconf\n"; - $failed_tests_data .= "Bundled Libtool:\n$libtool\n"; - $failed_tests_data .= "System Libtool:\n$sys_libtool\n"; - $failed_tests_data .= "Compiler:\n$compiler\n"; - $failed_tests_data .= "Bison:\n". shell_exec('bison --version 2>/dev/null') . "\n"; - $failed_tests_data .= "Libraries:\n$ldd\n"; - $failed_tests_data .= "\n"; - - if (isset($user_email)) { - $failed_tests_data .= "User's E-mail: " . $user_email . "\n\n"; - } - - $failed_tests_data .= $sep . "PHPINFO" . $sep; - $failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null'); - - if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status)) { - file_put_contents($output_file, $failed_tests_data); - - if (!$just_save_results) { - echo "\nThe test script was unable to automatically send the report to PHP's QA Team\n"; - } - - echo "Please send " . $output_file . " to " . PHP_QA_EMAIL . " manually, thank you.\n"; - } else { - fwrite($fp, "\nThank you for helping to make PHP better.\n"); - fclose($fp); - } - } - } -} - -// Determine the tests to be run. - -$test_files = array(); -$redir_tests = array(); -$test_results = array(); -$PHP_FAILED_TESTS = array('BORKED' => array(), 'FAILED' => array(), 'WARNED' => array(), 'LEAKED' => array(), 'XFAILED' => array()); - -// If parameters given assume they represent selected tests to run. -$failed_tests_file= false; -$pass_option_n = false; -$pass_options = ''; - -$compression = 0; -$output_file = $CUR_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt'; - -if ($compression) { - $output_file = 'compress.zlib://' . $output_file . '.gz'; -} - -$just_save_results = false; -$leak_check = false; -$html_output = false; -$html_file = null; -$temp_source = null; -$temp_target = null; -$temp_urlbase = null; -$conf_passed = null; -$no_clean = false; - -$cfgtypes = array('show', 'keep'); -$cfgfiles = array('skip', 'php', 'clean', 'out', 'diff', 'exp'); -$cfg = array(); - -foreach($cfgtypes as $type) { - $cfg[$type] = array(); - - foreach($cfgfiles as $file) { - $cfg[$type][$file] = false; - } -} - -if (getenv('TEST_PHP_ARGS')) { - - if (!isset($argc) || !$argc || !isset($argv)) { - $argv = array(__FILE__); - } - - $argv = array_merge($argv, split(' ', getenv('TEST_PHP_ARGS'))); - $argc = count($argv); -} - -if (isset($argc) && $argc > 1) { - - for ($i=1; $i<$argc; $i++) { - $is_switch = false; - $switch = substr($argv[$i],1,1); - $repeat = substr($argv[$i],0,1) == '-'; - - while ($repeat) { - - if (!$is_switch) { - $switch = substr($argv[$i],1,1); - } - - $is_switch = true; - - if ($repeat) { - foreach($cfgtypes as $type) { - if (strpos($switch, '--' . $type) === 0) { - foreach($cfgfiles as $file) { - if ($switch == '--' . $type . '-' . $file) { - $cfg[$type][$file] = true; - $is_switch = false; - break; - } - } - } - } - } - - if (!$is_switch) { - $is_switch = true; - break; - } - - $repeat = false; - - switch($switch) { - case 'r': - case 'l': - $test_list = file($argv[++$i]); - if ($test_list) { - foreach($test_list as $test) { - $matches = array(); - if (preg_match('/^#.*\[(.*)\]\:\s+(.*)$/', $test, $matches)) { - $redir_tests[] = array($matches[1], $matches[2]); - } else if (strlen($test)) { - $test_files[] = trim($test); - } - } - } - if ($switch != 'l') { - break; - } - $i--; - // break left intentionally - case 'w': - $failed_tests_file = fopen($argv[++$i], 'w+t'); - break; - case 'a': - $failed_tests_file = fopen($argv[++$i], 'a+t'); - break; - case 'c': - $conf_passed = $argv[++$i]; - break; - case 'd': - $ini_overwrites[] = $argv[++$i]; - break; - //case 'h' - case '--keep-all': - foreach($cfgfiles as $file) { - $cfg['keep'][$file] = true; - } - break; - //case 'l' - case 'm': - $leak_check = true; - $valgrind_cmd = "valgrind --version"; - $valgrind_header = system_with_timeout($valgrind_cmd); - $replace_count = 0; - if (!$valgrind_header) { - error("Valgrind returned no version info, cannot proceed.\nPlease check if Valgrind is installed."); - } else { - $valgrind_version = preg_replace("/valgrind-([0-9])\.([0-9])\.([0-9]+)([.-]\w+)?(\s+)/", '$1$2$3', $valgrind_header, 1, $replace_count); - if ($replace_count != 1 || !is_numeric($valgrind_version)) { - error("Valgrind returned invalid version info (\"$valgrind_header\"), cannot proceed."); - } - $valgrind_header = trim($valgrind_header); - } - break; - case 'n': - if (!$pass_option_n) { - $pass_options .= ' -n'; - } - $pass_option_n = true; - break; - case '--no-clean': - $no_clean = true; - break; - case 'p': - $php = $argv[++$i]; - putenv("TEST_PHP_EXECUTABLE=$php"); - break; - case 'q': - putenv('NO_INTERACTION=1'); - break; - //case 'r' - case 's': - $output_file = $argv[++$i]; - $just_save_results = true; - break; - case '--set-timeout': - $environment['TEST_TIMEOUT'] = $argv[++$i]; - break; - case '--show-all': - foreach($cfgfiles as $file) { - $cfg['show'][$file] = true; - } - break; - case '--temp-source': - $temp_source = $argv[++$i]; - break; - case '--temp-target': - $temp_target = $argv[++$i]; - if ($temp_urlbase) { - $temp_urlbase = $temp_target; - } - break; - case '--temp-urlbase': - $temp_urlbase = $argv[++$i]; - break; - case 'v': - case '--verbose': - $DETAILED = true; - break; - case 'x': - $environment['SKIP_SLOW_TESTS'] = 1; - break; - //case 'w' - case '-': - // repeat check with full switch - $switch = $argv[$i]; - if ($switch != '-') { - $repeat = true; - } - break; - case '--html': - $html_file = fopen($argv[++$i], 'wt'); - $html_output = is_resource($html_file); - break; - case '--version': - echo '$Revision: 1.226.2.37.2.51 $' . "\n"; - exit(1); - - default: - echo "Illegal switch '$switch' specified!\n"; - case 'h': - case '-help': - case '--help': - echo << Read the testfiles to be executed from . After the test - has finished all failed tests are written to the same . - If the list is empty and no further test is specified then - all tests are executed (same as: -r -w ). - - -r Read the testfiles to be executed from . - - -w Write a list of all failed tests to . - - -a Same as -w but append rather then truncating . - - -c Look for php.ini in directory or use as ini. - - -n Pass -n option to the php binary (Do not use a php.ini). - - -d foo=bar Pass -d option to the php binary (Define INI entry foo - with value 'bar'). - - -m Test for memory leaks with Valgrind. - - -p Specify PHP executable to run. - - -q Quiet, no user interaction (same as environment NO_INTERACTION). - - -s Write output to . - - -x Sets 'SKIP_SLOW_TESTS' environmental variable. - - --verbose - -v Verbose mode. - - --help - -h This Help. - - --html Generate HTML output. - - --temp-source --temp-target [--temp-urlbase ] - Write temporary files to by replacing from the - filenames to generate with . If --html is being used and - given then the generated links are relative and prefixed - with the given url. In general you want to make the path - to your source files and some pach in your web page - hierarchy with pointing to . - - --keep-[all|php|skip|clean] - Do not delete 'all' files, 'php' test file, 'skip' or 'clean' - file. - - --set-timeout [n] - Set timeout for individual tests, where [n] is the number of - seconds. The default value is 60 seconds, or 300 seconds when - testing for memory leaks. - - --show-[all|php|skip|clean|exp|diff|out] - Show 'all' files, 'php' test file, 'skip' or 'clean' file. You - can also use this to show the output 'out', the expected result - 'exp' or the difference between them 'diff'. The result types - get written independent of the log format, however 'diff' only - exists when a test fails. - - --no-clean Do not execute clean section if any. - -HELP; - exit(1); - } - } - - if (!$is_switch) { - $testfile = realpath($argv[$i]); - - if (!$testfile && strpos($argv[$i], '*') !== false && function_exists('glob')) { - - if (preg_match("/\.phpt$/", $argv[$i])) { - $pattern_match = glob($argv[$i]); - } else if (preg_match("/\*$/", $argv[$i])) { - $pattern_match = glob($argv[$i] . '.phpt'); - } else { - die("bogus test name " . $argv[$i] . "\n"); - } - - if (is_array($pattern_match)) { - $test_files = array_merge($test_files, $pattern_match); - } - - } else if (is_dir($testfile)) { - find_files($testfile); - } else if (preg_match("/\.phpt$/", $testfile)) { - $test_files[] = $testfile; - } else { - die("bogus test name " . $argv[$i] . "\n"); - } - } - } - - if (strlen($conf_passed)) { - if (substr(PHP_OS, 0, 3) == "WIN") { - $pass_options .= " -c " . escapeshellarg($conf_passed); - } else { - $pass_options .= " -c '$conf_passed'"; - } - } - - $test_files = array_unique($test_files); - $test_files = array_merge($test_files, $redir_tests); - - // Run selected tests. - $test_cnt = count($test_files); - - if ($test_cnt) { - putenv('NO_INTERACTION=1'); - verify_config(); - write_information($html_output); - usort($test_files, "test_sort"); - $start_time = time(); - - if (!$html_output) { - echo "Running selected tests.\n"; - } else { - show_start($start_time); - } - - $test_idx = 0; - run_all_tests($test_files, $environment); - $end_time = time(); - - if ($html_output) { - show_end($end_time); - } - - if ($failed_tests_file) { - fclose($failed_tests_file); - } - - if (count($test_files) || count($test_results)) { - compute_summary(); - if ($html_output) { - fwrite($html_file, "
\n" . get_summary(false, true)); - } - echo "====================================================================="; - echo get_summary(false, false); - } - - if ($html_output) { - fclose($html_file); - } - - if ($output_file != '' && $just_save_results) { - save_or_mail_results(); - } - - if (getenv('REPORT_EXIT_STATUS') == 1 and preg_match('/FAILED(?: |$)/', implode(' ', $test_results))) { - exit(1); - } - - exit(0); - } -} - -verify_config(); -write_information($html_output); - -// Compile a list of all test files (*.phpt). -$test_files = array(); -$exts_tested = count($exts_to_test); -$exts_skipped = 0; -$ignored_by_ext = 0; -sort($exts_to_test); -$test_dirs = array(); -$optionals = array('tests', 'ext', 'Zend', 'ZendEngine2', 'sapi/cli', 'sapi/cgi'); - -foreach($optionals as $dir) { - if (@filetype($dir) == 'dir') { - $test_dirs[] = $dir; - } -} - -// Convert extension names to lowercase -foreach ($exts_to_test as $key => $val) { - $exts_to_test[$key] = strtolower($val); -} - -foreach ($test_dirs as $dir) { - find_files("{$cwd}/{$dir}", ($dir == 'ext')); -} - -foreach ($user_tests as $dir) { - find_files($dir, ($dir == 'ext')); -} - -function find_files($dir, $is_ext_dir = false, $ignore = false) -{ - global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped, $exts_tested; - - $o = opendir($dir) or error("cannot open directory: $dir"); - - while (($name = readdir($o)) !== false) { - - if (is_dir("{$dir}/{$name}") && !in_array($name, array('.', '..', 'CVS'))) { - $skip_ext = ($is_ext_dir && !in_array(strtolower($name), $exts_to_test)); - if ($skip_ext) { - $exts_skipped++; - } - find_files("{$dir}/{$name}", false, $ignore || $skip_ext); - } - - // Cleanup any left-over tmp files from last run. - if (substr($name, -4) == '.tmp') { - @unlink("$dir/$name"); - continue; - } - - // Otherwise we're only interested in *.phpt files. - if (substr($name, -5) == '.phpt') { - if ($ignore) { - $ignored_by_ext++; - } else { - $testfile = realpath("{$dir}/{$name}"); - $test_files[] = $testfile; - } - } - } - - closedir($o); -} - -function test_name($name) -{ - if (is_array($name)) { - return $name[0] . ':' . $name[1]; - } else { - return $name; - } -} - -function test_sort($a, $b) -{ - global $cwd; - - $a = test_name($a); - $b = test_name($b); - - $ta = strpos($a, "{$cwd}/tests") === 0 ? 1 + (strpos($a, "{$cwd}/tests/run-test") === 0 ? 1 : 0) : 0; - $tb = strpos($b, "{$cwd}/tests") === 0 ? 1 + (strpos($b, "{$cwd}/tests/run-test") === 0 ? 1 : 0) : 0; - - if ($ta == $tb) { - return strcmp($a, $b); - } else { - return $tb - $ta; - } -} - -$test_files = array_unique($test_files); -usort($test_files, "test_sort"); - -$start_time = time(); -show_start($start_time); - -$test_cnt = count($test_files); -$test_idx = 0; -run_all_tests($test_files, $environment); -$end_time = time(); - -if ($failed_tests_file) { - fclose($failed_tests_file); -} - -// Summarize results - -if (0 == count($test_results)) { - echo "No tests were run.\n"; - return; -} - -compute_summary(); - -show_end($end_time); -show_summary(); - -if ($html_output) { - fclose($html_file); -} - -save_or_mail_results(); - -if (getenv('REPORT_EXIT_STATUS') == 1 and $sum_results['FAILED']) { - exit(1); -} -exit(0); - -// -// Send Email to QA Team -// - -function mail_qa_team($data, $compression, $status = false) -{ - $url_bits = parse_url(QA_SUBMISSION_PAGE); - - if (empty($url_bits['port'])) { - $url_bits['port'] = 80; - } - - $data = "php_test_data=" . urlencode(base64_encode(str_replace("\00", '[0x0]', $data))); - $data_length = strlen($data); - - $fs = fsockopen($url_bits['host'], $url_bits['port'], $errno, $errstr, 10); - - if (!$fs) { - return false; - } - - $php_version = urlencode(TESTED_PHP_VERSION); - - echo "\nPosting to {$url_bits['host']} {$url_bits['path']}\n"; - fwrite($fs, "POST " . $url_bits['path'] . "?status=$status&version=$php_version HTTP/1.1\r\n"); - fwrite($fs, "Host: " . $url_bits['host'] . "\r\n"); - fwrite($fs, "User-Agent: QA Browser 0.1\r\n"); - fwrite($fs, "Content-Type: application/x-www-form-urlencoded\r\n"); - fwrite($fs, "Content-Length: " . $data_length . "\r\n\r\n"); - fwrite($fs, $data); - fwrite($fs, "\r\n\r\n"); - fclose($fs); - - return 1; -} - - -// -// Write the given text to a temporary file, and return the filename. -// - -function save_text($filename, $text, $filename_copy = null) -{ - global $DETAILED; - - if ($filename_copy && $filename_copy != $filename) { - if (file_put_contents($filename_copy, (binary) $text, FILE_BINARY) === false) { - error("Cannot open file '" . $filename_copy . "' (save_text)"); - } - } - - if (file_put_contents($filename, (binary) $text, FILE_BINARY) === false) { - error("Cannot open file '" . $filename . "' (save_text)"); - } - - if (1 < $DETAILED) echo " -FILE $filename {{{ -$text -}}} -"; -} - -// -// Write an error in a format recognizable to Emacs or MSVC. -// - -function error_report($testname, $logname, $tested) -{ - $testname = realpath($testname); - $logname = realpath($logname); - - switch (strtoupper(getenv('TEST_PHP_ERROR_STYLE'))) { - case 'MSVC': - echo $testname . "(1) : $tested\n"; - echo $logname . "(1) : $tested\n"; - break; - case 'EMACS': - echo $testname . ":1: $tested\n"; - echo $logname . ":1: $tested\n"; - break; - } -} - -function system_with_timeout($commandline, $env = null, $stdin = null) -{ - global $leak_check; - - $data = ''; - - $proc = proc_open($commandline, array( - 0 => array('pipe', 'r'), - 1 => array('pipe', 'w'), - 2 => array('pipe', 'w') - ), $pipes, null, $env, array('suppress_errors' => true, 'binary_pipes' => true)); - - if (!$proc) { - return false; - } - - if (!is_null($stdin)) { - fwrite($pipes[0], (binary) $stdin); - } - fclose($pipes[0]); - - $timeout = $leak_check ? 300 : (isset($env['TEST_TIMEOUT']) ? $env['TEST_TIMEOUT'] : 60); - - while (true) { - /* hide errors from interrupted syscalls */ - $r = $pipes; - $w = null; - $e = null; - - $n = @stream_select($r, $w, $e, $timeout); - - if ($n === false) { - break; - } else if ($n === 0) { - /* timed out */ - $data .= "\n ** ERROR: process timed out **\n"; - proc_terminate($proc); - return $data; - } else if ($n > 0) { - $line = fread($pipes[1], 8192); - if (strlen($line) == 0) { - /* EOF */ - break; - } - $data .= (binary) $line; - } - } - - $stat = proc_get_status($proc); - - if ($stat['signaled']) { - $data .= "\nTermsig=" . $stat['stopsig']; - } - - $code = proc_close($proc); - return $data; -} - -function run_all_tests($test_files, $env, $redir_tested = null) -{ - global $test_results, $failed_tests_file, $php, $test_cnt, $test_idx; - - foreach($test_files as $name) { - - if (is_array($name)) { - $index = "# $name[1]: $name[0]"; - - if ($redir_tested) { - $name = $name[0]; - } - } else if ($redir_tested) { - $index = "# $redir_tested: $name"; - } else { - $index = $name; - } - $test_idx++; - $result = run_test($php, $name, $env); - - if (!is_array($name) && $result != 'REDIR') { - $test_results[$index] = $result; - if ($failed_tests_file && ($result == 'XFAILED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) { - fwrite($failed_tests_file, "$index\n"); - } - } - } -} - -// -// Show file or result block -// -function show_file_block($file, $block, $section = null) -{ - global $cfg; - - if ($cfg['show'][$file]) { - - if (is_null($section)) { - $section = strtoupper($file); - } - - echo "\n========" . $section . "========\n"; - echo rtrim($block); - echo "\n========DONE========\n"; - } -} - -// -// Run an individual test case. -// -function run_test($php, $file, $env) -{ - global $log_format, $info_params, $ini_overwrites, $cwd, $PHP_FAILED_TESTS; - global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx; - global $leak_check, $temp_source, $temp_target, $cfg, $environment; - global $no_clean; - global $valgrind_version; - - $temp_filenames = null; - $org_file = $file; - - if (isset($env['TEST_PHP_CGI_EXECUTABLE'])) { - $php_cgi = $env['TEST_PHP_CGI_EXECUTABLE']; - } - - if (is_array($file)) { - $file = $file[0]; - } - - if ($DETAILED) echo " -================= -TEST $file -"; - - // Load the sections of the test file. - $section_text = array('TEST' => ''); - - $fp = fopen($file, "rt") or error("Cannot open test file: $file"); - - $borked = false; - $bork_info = ''; - - if (!feof($fp)) { - $line = fgets($fp); - - if ($line === false) { - $bork_info = "cannot read test"; - $borked = true; - } - } else { - $bork_info = "empty test [$file]"; - $borked = true; - } - if (!$borked && strncmp('--TEST--', $line, 8)) { - $bork_info = "tests must start with --TEST-- [$file]"; - $borked = true; - } - - $section = 'TEST'; - $secfile = false; - $secdone = false; - - while (!feof($fp)) { - $line = fgets($fp); - - // Match the beginning of a section. - if (preg_match('/^--([_A-Z]+)--/', $line, $r)) { - $section = $r[1]; - - if (isset($section_text[$section])) { - $bork_info = "duplicated $section section"; - $borked = true; - } - - $section_text[$section] = ''; - $secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL'; - $secdone = false; - continue; - } - - // Add to the section text. - if (!$secdone) { - $section_text[$section] .= $line; - } - - // End of actual test? - if ($secfile && preg_match('/^===DONE===\s*$/', $line)) { - $secdone = true; - } - } - - // the redirect section allows a set of tests to be reused outside of - // a given test dir - if (!$borked) { - if (@count($section_text['REDIRECTTEST']) == 1) { - - if ($IN_REDIRECT) { - $borked = true; - $bork_info = "Can't redirect a test from within a redirected test"; - } else { - $borked = false; - } - - } else { - - if (@count($section_text['FILE']) + @count($section_text['FILEEOF']) + @count($section_text['FILE_EXTERNAL']) != 1) { - $bork_info = "missing section --FILE--"; - $borked = true; - } - - if (@count($section_text['FILEEOF']) == 1) { - $section_text['FILE'] = preg_replace("/[\r\n]+$/", '', $section_text['FILEEOF']); - unset($section_text['FILEEOF']); - } - - if (@count($section_text['FILE_EXTERNAL']) == 1) { - // don't allow tests to retrieve files from anywhere but this subdirectory - $section_text['FILE_EXTERNAL'] = dirname($file) . '/' . trim(str_replace('..', '', $section_text['FILE_EXTERNAL'])); - - if (file_exists($section_text['FILE_EXTERNAL'])) { - $section_text['FILE'] = file_get_contents($section_text['FILE_EXTERNAL']); - unset($section_text['FILE_EXTERNAL']); - } else { - $bork_info = "could not load --FILE_EXTERNAL-- " . dirname($file) . '/' . trim($section_text['FILE_EXTERNAL']); - $borked = true; - } - } - - if ((@count($section_text['EXPECT']) + @count($section_text['EXPECTF']) + @count($section_text['EXPECTREGEX'])) != 1) { - $bork_info = "missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--"; - $borked = true; - } - } - } - fclose($fp); - - $shortname = str_replace($cwd . '/', '', $file); - $tested_file = $shortname; - - if ($borked) { - show_result("BORK", $bork_info, $tested_file); - $PHP_FAILED_TESTS['BORKED'][] = array ( - 'name' => $file, - 'test_name' => '', - 'output' => '', - 'diff' => '', - 'info' => "$bork_info [$file]", - ); - return 'BORKED'; - } - - $tested = trim($section_text['TEST']); - - /* For GET/POST tests, check if cgi sapi is available and if it is, use it. */ - if (!empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { - if (isset($php_cgi)) { - $old_php = $php; - $php = $php_cgi . ' -C '; - } else if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/php-cgi.exe")) { - $old_php = $php; - $php = realpath(dirname($php) . "/php-cgi.exe") . ' -C '; - } else { - if (file_exists(dirname($php) . "/../../sapi/cgi/php-cgi")) { - $old_php = $php; - $php = realpath(dirname($php) . "/../../sapi/cgi/php-cgi") . ' -C '; - } else if (file_exists("./sapi/cgi/php-cgi")) { - $old_php = $php; - $php = realpath("./sapi/cgi/php-cgi") . ' -C '; - } else { - show_result('SKIP', $tested, $tested_file, "reason: CGI not available"); - return 'SKIPPED'; - } - } - } - - show_test($test_idx, $shortname); - - if (is_array($IN_REDIRECT)) { - $temp_dir = $test_dir = $IN_REDIRECT['dir']; - } else { - $temp_dir = $test_dir = realpath(dirname($file)); - } - - if ($temp_source && $temp_target) { - $temp_dir = str_replace($temp_source, $temp_target, $temp_dir); - } - - $main_file_name = basename($file,'phpt'); - - $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'diff'; - $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'log'; - $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'exp'; - $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'out'; - $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'mem'; - $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php'; - $test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php'; - $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php'; - $test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php'; - $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php'; - $test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php'; - $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('/phpt.'); - $tmp_relative_file = str_replace(realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR, '', $test_file) . 't'; - - if ($temp_source && $temp_target) { - $temp_skipif .= 's'; - $temp_file .= 's'; - $temp_clean .= 's'; - $copy_file = $temp_dir . DIRECTORY_SEPARATOR . basename(is_array($file) ? $file[1] : $file) . '.phps'; - - if (!is_dir(dirname($copy_file))) { - mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file)); - } - - if (isset($section_text['FILE'])) { - save_text($copy_file, $section_text['FILE']); - } - - $temp_filenames = array( - 'file' => $copy_file, - 'diff' => $diff_filename, - 'log' => $log_filename, - 'exp' => $exp_filename, - 'out' => $output_filename, - 'mem' => $memcheck_filename, - 'php' => $temp_file, - 'skip' => $temp_skipif, - 'clean'=> $temp_clean); - } - - if (is_array($IN_REDIRECT)) { - $tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']); - $tested_file = $tmp_relative_file; - $section_text['FILE'] = "# original source file: $shortname\n" . $section_text['FILE']; - } - - // unlink old test results - @unlink($diff_filename); - @unlink($log_filename); - @unlink($exp_filename); - @unlink($output_filename); - @unlink($memcheck_filename); - @unlink($temp_file); - @unlink($test_file); - @unlink($temp_skipif); - @unlink($test_skipif); - @unlink($tmp_post); - @unlink($temp_clean); - @unlink($test_clean); - - // Reset environment from any previous test. - $env['REDIRECT_STATUS'] = ''; - $env['QUERY_STRING'] = ''; - $env['PATH_TRANSLATED'] = ''; - $env['SCRIPT_FILENAME'] = ''; - $env['REQUEST_METHOD'] = ''; - $env['CONTENT_TYPE'] = ''; - $env['CONTENT_LENGTH'] = ''; - - if (!empty($section_text['ENV'])) { - - foreach(explode("\n", trim($section_text['ENV'])) as $e) { - $e = explode('=', trim($e), 2); - - if (!empty($e[0]) && isset($e[1])) { - $env[$e[0]] = $e[1]; - } - } - } - - // Default ini settings - $ini_settings = array(); - // additional ini overwrites - //$ini_overwrites[] = 'setting=value'; - settings2array($ini_overwrites, $ini_settings); - - // Any special ini settings - // these may overwrite the test defaults... - if (array_key_exists('INI', $section_text)) { - if (strpos($section_text['INI'], '{PWD}') !== false) { - $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']); - } - settings2array(preg_split( "/[\n\r]+/", $section_text['INI']), $ini_settings); - } - - settings2params($ini_settings); - - // Check if test should be skipped. - $info = ''; - $warn = false; - - if (array_key_exists('SKIPIF', $section_text)) { - - if (trim($section_text['SKIPIF'])) { - show_file_block('skip', $section_text['SKIPIF']); - save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif); - $extra = substr(PHP_OS, 0, 3) !== "WIN" ? - "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;": ""; - - if ($leak_check) { - $env['USE_ZEND_ALLOC'] = '0'; - } else { - $env['USE_ZEND_ALLOC'] = '1'; - } - - $output = system_with_timeout("$extra $php $pass_options -q $ini_settings $test_skipif", $env); - - if (!$cfg['keep']['skip']) { - @unlink($test_skipif); - } - - if (!strncasecmp('skip', ltrim($output), 4)) { - - if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) { - show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames); - } else { - show_result('SKIP', $tested, $tested_file, '', $temp_filenames); - } - - if (isset($old_php)) { - $php = $old_php; - } - - if (!$cfg['keep']['skip']) { - @unlink($test_skipif); - } - - return 'SKIPPED'; - } - - if (!strncasecmp('info', ltrim($output), 4)) { - if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) { - $info = " (info: $m[1])"; - } - } - - if (!strncasecmp('warn', ltrim($output), 4)) { - if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) { - $warn = true; /* only if there is a reason */ - $info = " (warn: $m[1])"; - } - } - } - } - - if (@count($section_text['REDIRECTTEST']) == 1) { - $test_files = array(); - - $IN_REDIRECT = eval($section_text['REDIRECTTEST']); - $IN_REDIRECT['via'] = "via [$shortname]\n\t"; - $IN_REDIRECT['dir'] = realpath(dirname($file)); - $IN_REDIRECT['prefix'] = trim($section_text['TEST']); - - if (count($IN_REDIRECT['TESTS']) == 1) { - - if (is_array($org_file)) { - $test_files[] = $org_file[1]; - } else { - $GLOBALS['test_files'] = $test_files; - find_files($IN_REDIRECT['TESTS']); - - foreach($GLOBALS['test_files'] as $f) { - $test_files[] = array($f, $file); - } - } - $test_cnt += @count($test_files) - 1; - $test_idx--; - - show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file); - - // set up environment - $redirenv = array_merge($environment, $IN_REDIRECT['ENV']); - $redirenv['REDIR_TEST_DIR'] = realpath($IN_REDIRECT['TESTS']) . DIRECTORY_SEPARATOR; - - usort($test_files, "test_sort"); - run_all_tests($test_files, $redirenv, $tested); - - show_redirect_ends($IN_REDIRECT['TESTS'], $tested, $tested_file); - - // a redirected test never fails - $IN_REDIRECT = false; - return 'REDIR'; - - } else { - - $bork_info = "Redirect info must contain exactly one TEST string to be used as redirect directory."; - show_result("BORK", $bork_info, '', $temp_filenames); - $PHP_FAILED_TESTS['BORKED'][] = array ( - 'name' => $file, - 'test_name' => '', - 'output' => '', - 'diff' => '', - 'info' => "$bork_info [$file]", - ); - } - } - - if (is_array($org_file) || @count($section_text['REDIRECTTEST']) == 1) { - - if (is_array($org_file)) { - $file = $org_file[0]; - } - - $bork_info = "Redirected test did not contain redirection info"; - show_result("BORK", $bork_info, '', $temp_filenames); - $PHP_FAILED_TESTS['BORKED'][] = array ( - 'name' => $file, - 'test_name' => '', - 'output' => '', - 'diff' => '', - 'info' => "$bork_info [$file]", - ); - return 'BORKED'; - } - - // We've satisfied the preconditions - run the test! - show_file_block('php', $section_text['FILE'], 'TEST'); - save_text($test_file, $section_text['FILE'], $temp_file); - - if (array_key_exists('GET', $section_text)) { - $query_string = trim($section_text['GET']); - } else { - $query_string = ''; - } - - $env['REDIRECT_STATUS'] = '1'; - $env['QUERY_STRING'] = $query_string; - $env['PATH_TRANSLATED'] = $test_file; - $env['SCRIPT_FILENAME'] = $test_file; - - if (array_key_exists('COOKIE', $section_text)) { - $env['HTTP_COOKIE'] = trim($section_text['COOKIE']); - } else { - $env['HTTP_COOKIE'] = ''; - } - - $args = isset($section_text['ARGS']) ? ' -- ' . $section_text['ARGS'] : ''; - - if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) { - - $post = trim($section_text['POST_RAW']); - $raw_lines = explode("\n", $post); - - $request = ''; - $started = false; - - foreach ($raw_lines as $line) { - - if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) { - $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); - continue; - } - - if ($started) { - $request .= "\n"; - } - - $started = true; - $request .= $line; - } - - $env['CONTENT_LENGTH'] = strlen($request); - $env['REQUEST_METHOD'] = 'POST'; - - if (empty($request)) { - return 'BORKED'; - } - - save_text($tmp_post, $request); - $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < $tmp_post"; - - } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { - - $post = trim($section_text['POST']); - - if (array_key_exists('GZIP_POST', $section_text) && function_exists('gzencode')) { - $post = gzencode($post, 9, FORCE_GZIP); - $env['HTTP_CONTENT_ENCODING'] = 'gzip'; - } else if (array_key_exists('DEFLATE_POST', $section_text) && function_exists('gzcompress')) { - $post = gzcompress($post, 9); - $env['HTTP_CONTENT_ENCODING'] = 'deflate'; - } - - save_text($tmp_post, $post); - $content_length = strlen($post); - - $env['REQUEST_METHOD'] = 'POST'; - $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; - $env['CONTENT_LENGTH'] = $content_length; - - $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < $tmp_post"; - - } else { - - $env['REQUEST_METHOD'] = 'GET'; - $env['CONTENT_TYPE'] = ''; - $env['CONTENT_LENGTH'] = ''; - - $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args 2>&1"; - } - - if ($leak_check) { - $env['USE_ZEND_ALLOC'] = '0'; - - if ($valgrind_version >= 330) { - /* valgrind 3.3.0+ doesn't have --log-file-exactly option */ - $cmd = "valgrind -q --tool=memcheck --trace-children=yes --log-file=$memcheck_filename $cmd"; - } else { - $cmd = "valgrind -q --tool=memcheck --trace-children=yes --log-file-exactly=$memcheck_filename $cmd"; - } - - } else { - $env['USE_ZEND_ALLOC'] = '1'; - } - - if ($DETAILED) echo " -CONTENT_LENGTH = " . $env['CONTENT_LENGTH'] . " -CONTENT_TYPE = " . $env['CONTENT_TYPE'] . " -PATH_TRANSLATED = " . $env['PATH_TRANSLATED'] . " -QUERY_STRING = " . $env['QUERY_STRING'] . " -REDIRECT_STATUS = " . $env['REDIRECT_STATUS'] . " -REQUEST_METHOD = " . $env['REQUEST_METHOD'] . " -SCRIPT_FILENAME = " . $env['SCRIPT_FILENAME'] . " -HTTP_COOKIE = " . $env['HTTP_COOKIE'] . " -COMMAND $cmd -"; - - $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null); - - if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) { - - if (trim($section_text['CLEAN'])) { - show_file_block('clean', $section_text['CLEAN']); - save_text($test_clean, trim($section_text['CLEAN']), $temp_clean); - - if (!$no_clean) { - $clean_params = array(); - settings2array($ini_overwrites, $clean_params); - settings2params($clean_params); - $extra = substr(PHP_OS, 0, 3) !== "WIN" ? - "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;": ""; - system_with_timeout("$extra $php $pass_options -q $clean_params $test_clean", $env); - } - - if (!$cfg['keep']['clean']) { - @unlink($test_clean); - } - } - } - - @unlink($tmp_post); - - $leaked = false; - $passed = false; - - if ($leak_check) { // leak check - $leaked = filesize($memcheck_filename) > 0; - - if (!$leaked) { - @unlink($memcheck_filename); - } - } - - // Does the output match what is expected? - $output = preg_replace("/\r\n/", "\n", trim($out)); - - /* when using CGI, strip the headers from the output */ - $headers = ""; - - if (isset($old_php) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) { - $output = trim($match[2]); - $rh = preg_split("/[\n\r]+/", $match[1]); - $headers = array(); - - foreach ($rh as $line) { - if (strpos($line, ':') !== false) { - $line = explode(':', $line, 2); - $headers[trim($line[0])] = trim($line[1]); - } - } - } - - $failed_headers = false; - - if (isset($section_text['EXPECTHEADERS'])) { - $want = array(); - $wanted_headers = array(); - $lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']); - - foreach($lines as $line) { - if (strpos($line, ':') !== false) { - $line = explode(':', $line, 2); - $want[trim($line[0])] = trim($line[1]); - $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]); - } - } - - $org_headers = $headers; - $headers = array(); - $output_headers = array(); - - foreach($want as $k => $v) { - - if (isset($org_headers[$k])) { - $headers = $org_headers[$k]; - $output_headers[] = $k . ': ' . $org_headers[$k]; - } - - if (!isset($org_headers[$k]) || $org_headers[$k] != $v) { - $failed_headers = true; - } - } - - ksort($wanted_headers); - $wanted_headers = join("\n", $wanted_headers); - ksort($output_headers); - $output_headers = join("\n", $output_headers); - } - - show_file_block('out', $output); - - if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) { - - if (isset($section_text['EXPECTF'])) { - $wanted = trim($section_text['EXPECTF']); - } else { - $wanted = trim($section_text['EXPECTREGEX']); - } - - show_file_block('exp', $wanted); - $wanted_re = preg_replace('/\r\n/', "\n", $wanted); - - if (isset($section_text['EXPECTF'])) { - $wanted_re = preg_quote($wanted_re, '/'); - $wanted_re = str_replace( - array('%unicode_string_optional%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? 'string' : 'Unicode string', - $wanted_re - ); - $wanted_re = str_replace( - array('%unicode\|string%', '%string\|unicode%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? 'string' : 'unicode', - $wanted_re - ); - $wanted_re = str_replace( - array('%u\|b%', '%b\|u%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? '' : 'u', - $wanted_re - ); - // Stick to basics - $wanted_re = str_replace('%e', '\\' . DIRECTORY_SEPARATOR, $wanted_re); - $wanted_re = str_replace('%s', '[^\r\n]+', $wanted_re); - $wanted_re = str_replace('%a', '.+', $wanted_re); - $wanted_re = str_replace('%w', '\s*', $wanted_re); - $wanted_re = str_replace('%i', '[+-]?\d+', $wanted_re); - $wanted_re = str_replace('%d', '\d+', $wanted_re); - $wanted_re = str_replace('%x', '[0-9a-fA-F]+', $wanted_re); - $wanted_re = str_replace('%f', '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re); - $wanted_re = str_replace('%c', '.', $wanted_re); - // %f allows two points "-.0.0" but that is the best *simple* expression - } -/* DEBUG YOUR REGEX HERE - var_dump($wanted_re); - print(str_repeat('=', 80) . "\n"); - var_dump($output); -*/ - if (preg_match((binary) "/^$wanted_re\$/s", $output)) { - $passed = true; - if (!$cfg['keep']['php']) { - @unlink($test_file); - } - if (isset($old_php)) { - $php = $old_php; - } - if (!$leaked && !$failed_headers) { - show_result("PASS", $tested, $tested_file, '', $temp_filenames); - return 'PASSED'; - } - } - - } else { - - $wanted = trim($section_text['EXPECT']); - $wanted = preg_replace('/\r\n/',"\n", $wanted); - show_file_block('exp', $wanted); - - // compare and leave on success - if (!strcmp($output, $wanted)) { - $passed = true; - - if (!$cfg['keep']['php']) { - @unlink($test_file); - } - - if (isset($old_php)) { - $php = $old_php; - } - - if (!$leaked && !$failed_headers) { - show_result("PASS", $tested, $tested_file, '', $temp_filenames); - return 'PASSED'; - } - } - - $wanted_re = null; - } - - // Test failed so we need to report details. - if ($failed_headers) { - $passed = false; - $wanted = $wanted_headers . "\n--HEADERS--\n" . $wanted; - $output = $output_headers . "\n--HEADERS--\n" . $output; - - if (isset($wanted_re)) { - $wanted_re = preg_quote($wanted_headers . "\n--HEADERS--\n", '/') . $wanted_re; - } - } - - if ($leaked) { - $restype[] = 'LEAK'; - } - - if ($warn) { - $restype[] = 'WARN'; - } - - if (!$passed) { - if (isset($section_text['XFAIL'])) { - $restype[] = 'XFAIL'; - } else { - $restype[] = 'FAIL'; - } - } - - if (!$passed) { - - // write .exp - if (strpos($log_format, 'E') !== false && file_put_contents($exp_filename, (binary) $wanted, FILE_BINARY) === false) { - error("Cannot create expected test output - $exp_filename"); - } - - // write .out - if (strpos($log_format, 'O') !== false && file_put_contents($output_filename, (binary) $output, FILE_BINARY) === false) { - error("Cannot create test output - $output_filename"); - } - - // write .diff - $diff = generate_diff($wanted, $wanted_re, $output); - show_file_block('diff', $diff); - if (strpos($log_format, 'D') !== false && file_put_contents($diff_filename, (binary) $diff, FILE_BINARY) === false) { - error("Cannot create test diff - $diff_filename"); - } - - // write .log - if (strpos($log_format, 'L') !== false && file_put_contents($log_filename, b" ----- EXPECTED OUTPUT -$wanted ----- ACTUAL OUTPUT -$output ----- FAILED -", FILE_BINARY) === false) { - error("Cannot create test log - $log_filename"); - error_report($file, $log_filename, $tested); - } - } - - show_result(implode('&', $restype), $tested, $tested_file, $info, $temp_filenames); - - foreach ($restype as $type) { - $PHP_FAILED_TESTS[$type.'ED'][] = array ( - 'name' => $file, - 'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]", - 'output' => $output_filename, - 'diff' => $diff_filename, - 'info' => $info, - ); - } - - if (isset($old_php)) { - $php = $old_php; - } - - return $restype[0] . 'ED'; -} - -function comp_line($l1, $l2, $is_reg) -{ - if ($is_reg) { - return preg_match((binary) "/^$l1$/s", (binary) $l2); - } else { - return !strcmp((binary) $l1, (binary) $l2); - } -} - -function count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2, $cnt1, $cnt2, $steps) -{ - $equal = 0; - - while ($idx1 < $cnt1 && $idx2 < $cnt2 && comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) { - $idx1++; - $idx2++; - $equal++; - $steps--; - } - if (--$steps > 0) { - $eq1 = 0; - $st = $steps / 2; - - for ($ofs1 = $idx1 + 1; $ofs1 < $cnt1 && $st-- > 0; $ofs1++) { - $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $ofs1, $idx2, $cnt1, $cnt2, $st); - - if ($eq > $eq1) { - $eq1 = $eq; - } - } - - $eq2 = 0; - $st = $steps; - - for ($ofs2 = $idx2 + 1; $ofs2 < $cnt2 && $st-- > 0; $ofs2++) { - $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $ofs2, $cnt1, $cnt2, $st); - if ($eq > $eq2) { - $eq2 = $eq; - } - } - - if ($eq1 > $eq2) { - $equal += $eq1; - } else if ($eq2 > 0) { - $equal += $eq2; - } - } - - return $equal; -} - -function generate_array_diff($ar1, $ar2, $is_reg, $w) -{ - $idx1 = 0; $ofs1 = 0; $cnt1 = @count($ar1); - $idx2 = 0; $ofs2 = 0; $cnt2 = @count($ar2); - $diff = array(); - $old1 = array(); - $old2 = array(); - - while ($idx1 < $cnt1 && $idx2 < $cnt2) { - - if (comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) { - $idx1++; - $idx2++; - continue; - } else { - - $c1 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1+1, $idx2, $cnt1, $cnt2, 10); - $c2 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2+1, $cnt1, $cnt2, 10); - - if ($c1 > $c2) { - $old1[$idx1] = (binary) sprintf("%03d- ", $idx1+1) . $w[$idx1++]; - $last = 1; - } else if ($c2 > 0) { - $old2[$idx2] = (binary) sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++]; - $last = 2; - } else { - $old1[$idx1] = (binary) sprintf("%03d- ", $idx1+1) . $w[$idx1++]; - $old2[$idx2] = (binary) sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++]; - } - } - } - - reset($old1); $k1 = key($old1); $l1 = -2; - reset($old2); $k2 = key($old2); $l2 = -2; - - while ($k1 !== null || $k2 !== null) { - - if ($k1 == $l1 + 1 || $k2 === null) { - $l1 = $k1; - $diff[] = current($old1); - $k1 = next($old1) ? key($old1) : null; - } else if ($k2 == $l2 + 1 || $k1 === null) { - $l2 = $k2; - $diff[] = current($old2); - $k2 = next($old2) ? key($old2) : null; - } else if ($k1 < $k2) { - $l1 = $k1; - $diff[] = current($old1); - $k1 = next($old1) ? key($old1) : null; - } else { - $l2 = $k2; - $diff[] = current($old2); - $k2 = next($old2) ? key($old2) : null; - } - } - - while ($idx1 < $cnt1) { - $diff[] = (binary) sprintf("%03d- ", $idx1 + 1) . $w[$idx1++]; - } - - while ($idx2 < $cnt2) { - $diff[] = (binary) sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++]; - } - - return $diff; -} - -function generate_diff($wanted, $wanted_re, $output) -{ - $w = explode(b"\n", $wanted); - $o = explode(b"\n", $output); - $r = is_null($wanted_re) ? $w : explode(b"\n", $wanted_re); - $diff = generate_array_diff($r, $o, !is_null($wanted_re), $w); - - return implode(b"\r\n", $diff); -} - -function error($message) -{ - echo "ERROR: {$message}\n"; - exit(1); -} - -function settings2array($settings, &$ini_settings) -{ - foreach($settings as $setting) { - - if (strpos($setting, '=') !== false) { - $setting = explode("=", $setting, 2); - $name = trim(strtolower($setting[0])); - $value = trim($setting[1]); - - if ($name == 'extension') { - - if (!isset($ini_settings[$name])) { - $ini_settings[$name] = array(); - } - - $ini_settings[$name][] = $value; - - } else { - $ini_settings[$name] = $value; - } - } - } -} - -function settings2params(&$ini_settings) -{ - $settings = ''; - - foreach($ini_settings as $name => $value) { - - if (is_array($value)) { - foreach($value as $val) { - $val = addslashes($val); - $settings .= " -d \"$name=$val\""; - } - } else { - $value = addslashes($value); - $settings .= " -d \"$name=$value\""; - } - } - - $ini_settings = $settings; -} - -function compute_summary() -{ - global $n_total, $test_results, $ignored_by_ext, $sum_results, $percent_results; - - $n_total = count($test_results); - $n_total += $ignored_by_ext; - $sum_results = array( - 'PASSED' => 0, - 'WARNED' => 0, - 'SKIPPED' => 0, - 'FAILED' => 0, - 'BORKED' => 0, - 'LEAKED' => 0, - 'XFAILED' => 0 - ); - - foreach ($test_results as $v) { - $sum_results[$v]++; - } - - $sum_results['SKIPPED'] += $ignored_by_ext; - $percent_results = array(); - - while (list($v, $n) = each($sum_results)) { - $percent_results[$v] = (100.0 * $n) / $n_total; - } -} - -function get_summary($show_ext_summary, $show_html) -{ - global $exts_skipped, $exts_tested, $n_total, $sum_results, $percent_results, $end_time, $start_time, $failed_test_summary, $PHP_FAILED_TESTS, $leak_check; - - $x_total = $n_total - $sum_results['SKIPPED'] - $sum_results['BORKED']; - - if ($x_total) { - $x_warned = (100.0 * $sum_results['WARNED']) / $x_total; - $x_failed = (100.0 * $sum_results['FAILED']) / $x_total; - $x_xfailed = (100.0 * $sum_results['XFAILED']) / $x_total; - $x_leaked = (100.0 * $sum_results['LEAKED']) / $x_total; - $x_passed = (100.0 * $sum_results['PASSED']) / $x_total; - } else { - $x_warned = $x_failed = $x_passed = $x_leaked = $x_xfailed = 0; - } - - $summary = ''; - - if ($show_html) { - $summary .= "
\n";
-	}
-	
-	if ($show_ext_summary) {
-		$summary .= '
-=====================================================================
-TEST RESULT SUMMARY
----------------------------------------------------------------------
-Exts skipped    : ' . sprintf('%4d', $exts_skipped) . '
-Exts tested     : ' . sprintf('%4d', $exts_tested) . '
----------------------------------------------------------------------
-';
-	}
-
-	$summary .= '
-Number of tests : ' . sprintf('%4d', $n_total) . '          ' . sprintf('%8d', $x_total);
-
-	if ($sum_results['BORKED']) {
-		$summary .= '
-Tests borked    : ' . sprintf('%4d (%5.1f%%)', $sum_results['BORKED'], $percent_results['BORKED']) . ' --------';
-	}
-
-	$summary .= '
-Tests skipped   : ' . sprintf('%4d (%5.1f%%)', $sum_results['SKIPPED'], $percent_results['SKIPPED']) . ' --------
-Tests warned    : ' . sprintf('%4d (%5.1f%%)', $sum_results['WARNED'], $percent_results['WARNED']) . ' ' . sprintf('(%5.1f%%)', $x_warned) . '
-Tests failed    : ' . sprintf('%4d (%5.1f%%)', $sum_results['FAILED'], $percent_results['FAILED']) . ' ' . sprintf('(%5.1f%%)', $x_failed) . '
-Expected fail   : ' . sprintf('%4d (%5.1f%%)', $sum_results['XFAILED'], $percent_results['XFAILED']) . ' ' . sprintf('(%5.1f%%)', $x_xfailed);
-
-	if ($leak_check) {
-		$summary .= '
-Tests leaked    : ' . sprintf('%4d (%5.1f%%)', $sum_results['LEAKED'], $percent_results['LEAKED']) . ' ' . sprintf('(%5.1f%%)', $x_leaked);
-	}
-
-	$summary .= '
-Tests passed    : ' . sprintf('%4d (%5.1f%%)', $sum_results['PASSED'], $percent_results['PASSED']) . ' ' . sprintf('(%5.1f%%)', $x_passed) . '
----------------------------------------------------------------------
-Time taken      : ' . sprintf('%4d seconds', $end_time - $start_time) . '
-=====================================================================
-';
-	$failed_test_summary = '';
-
-	if (count($PHP_FAILED_TESTS['BORKED'])) {
-		$failed_test_summary .= '
-=====================================================================
-BORKED TEST SUMMARY
----------------------------------------------------------------------
-';
-		foreach ($PHP_FAILED_TESTS['BORKED'] as $failed_test_data) {
-			$failed_test_summary .= $failed_test_data['info'] . "\n";
-		}
-
-		$failed_test_summary .=  "=====================================================================\n";
-	}
-
-	if (count($PHP_FAILED_TESTS['FAILED'])) {
-		$failed_test_summary .= '
-=====================================================================
-FAILED TEST SUMMARY
----------------------------------------------------------------------
-';
-		foreach ($PHP_FAILED_TESTS['FAILED'] as $failed_test_data) {
-			$failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
-		}
-		$failed_test_summary .=  "=====================================================================\n";
-	}
-	if (count($PHP_FAILED_TESTS['XFAILED'])) {
-		$failed_test_summary .= '
-=====================================================================
-EXPECTED FAILED TEST SUMMARY
----------------------------------------------------------------------
-';
-		foreach ($PHP_FAILED_TESTS['XFAILED'] as $failed_test_data) {
-			$failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
-		}
-		$failed_test_summary .=  "=====================================================================\n";
-	}
-
-	if (count($PHP_FAILED_TESTS['LEAKED'])) {
-		$failed_test_summary .= '
-=====================================================================
-LEAKED TEST SUMMARY
----------------------------------------------------------------------
-';
-		foreach ($PHP_FAILED_TESTS['LEAKED'] as $failed_test_data) {
-			$failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
-		}
-
-		$failed_test_summary .=  "=====================================================================\n";
-	}
-
-	if ($failed_test_summary && !getenv('NO_PHPTEST_SUMMARY')) {
-		$summary .= $failed_test_summary;
-	}
-
-	if ($show_html) {
-		$summary .= "
"; - } - - return $summary; -} - -function show_start($start_time) -{ - global $html_output, $html_file; - - if ($html_output) { - fwrite($html_file, "

Time Start: " . date('Y-m-d H:i:s', $start_time) . "

\n"); - fwrite($html_file, "\n"); - } - - echo "TIME START " . date('Y-m-d H:i:s', $start_time) . "\n=====================================================================\n"; -} - -function show_end($end_time) -{ - global $html_output, $html_file; - - if ($html_output) { - fwrite($html_file, "
\n"); - fwrite($html_file, "

Time End: " . date('Y-m-d H:i:s', $end_time) . "

\n"); - } - - echo "=====================================================================\nTIME END " . date('Y-m-d H:i:s', $end_time) . "\n"; -} - -function show_summary() -{ - global $html_output, $html_file; - - if ($html_output) { - fwrite($html_file, "
\n" . get_summary(true, true)); - } - - echo get_summary(true, false); -} - -function show_redirect_start($tests, $tested, $tested_file) -{ - global $html_output, $html_file; - - if ($html_output) { - fwrite($html_file, "---> $tests ($tested [$tested_file]) begin\n"); - } - - echo "---> $tests ($tested [$tested_file]) begin\n"; -} - -function show_redirect_ends($tests, $tested, $tested_file) -{ - global $html_output, $html_file; - - if ($html_output) { - fwrite($html_file, "---> $tests ($tested [$tested_file]) done\n"); - } - - echo "---> $tests ($tested [$tested_file]) done\n"; -} - -function show_test($test_idx, $shortname) -{ - global $test_cnt; - - echo "TEST $test_idx/$test_cnt [$shortname]\r"; - flush(); -} - -function show_result($result, $tested, $tested_file, $extra = '', $temp_filenames = null) -{ - global $html_output, $html_file, $temp_target, $temp_urlbase; - - echo "$result $tested [$tested_file] $extra\n"; - - if ($html_output) { - - if (isset($temp_filenames['file']) && file_exists($temp_filenames['file'])) { - $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['file']); - $tested = "$tested"; - } - - if (isset($temp_filenames['skip']) && file_exists($temp_filenames['skip'])) { - - if (empty($extra)) { - $extra = "skipif"; - } - - $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['skip']); - $extra = "$extra"; - - } else if (empty($extra)) { - $extra = " "; - } - - if (isset($temp_filenames['diff']) && file_exists($temp_filenames['diff'])) { - $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['diff']); - $diff = "diff"; - } else { - $diff = " "; - } - - if (isset($temp_filenames['mem']) && file_exists($temp_filenames['mem'])) { - $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['mem']); - $mem = "leaks"; - } else { - $mem = " "; - } - - fwrite($html_file, - "" . - "$result" . - "$tested" . - "$extra" . - "$diff" . - "$mem" . - "\n"); - } -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim: noet sw=4 ts=4 - */ -?> diff --git a/ffmpeg-php/test_ffmpeg.php b/ffmpeg-php/test_ffmpeg.php deleted file mode 100644 index 8f8f6d5..0000000 --- a/ffmpeg-php/test_ffmpeg.php +++ /dev/null @@ -1,106 +0,0 @@ -'; -} - -printf("ffmpeg-php version string: %s\n", FFMPEG_PHP_VERSION_STRING); -printf("ffmpeg-php build date string: %s\n", FFMPEG_PHP_BUILD_DATE_STRING); -printf("libavcodec build number: %d\n", LIBAVCODEC_BUILD_NUMBER); -printf("libavcodec version number: %d\n", LIBAVCODEC_VERSION_NUMBER); - -print_class_methods("ffmpeg_movie"); -print_class_methods("ffmpeg_frame"); - -// get an array for movies from the test media directory -$movies = getDirFiles(dirname(__FILE__) . '/tests/test_media'); - -echo "--------------------\n\n"; -foreach($movies as $movie) { - $mov = new ffmpeg_movie($movie); - printf("file name = %s\n", $mov->getFileName()); - printf("duration = %s seconds\n", $mov->getDuration()); - printf("frame count = %s\n", $mov->getFrameCount()); - printf("frame rate = %0.3f fps\n", $mov->getFrameRate()); - printf("comment = %s\n", $mov->getComment()); - printf("title = %s\n", $mov->getTitle()); - printf("author = %s\n", $mov->getAuthor()); - printf("copyright = %s\n", $mov->getCopyright()); - printf("get bit rate = %d\n", $mov->getBitRate()); - printf("has audio = %s\n", $mov->hasAudio() == 0 ? 'No' : 'Yes'); - if ($mov->hasAudio()) { - printf("get audio stream id= %s\n", $mov->getAudioStreamId()); - printf("get audio codec = %s\n", $mov->getAudioCodec()); - printf("get audio bit rate = %d\n", $mov->getAudioBitRate()); - printf("get audio sample rate = %d \n", $mov->getAudioSampleRate()); - printf("get audio channels = %s\n", $mov->getAudioChannels()); - } - printf("has video = %s\n", $mov->hasVideo() == 0 ? 'No' : 'Yes'); - if ($mov->hasVideo()) { - printf("frame height = %d pixels\n", $mov->getFrameHeight()); - printf("frame width = %d pixels\n", $mov->getFrameWidth()); - printf("get video stream id= %s\n", $mov->getVideoStreamId()); - printf("get video codec = %s\n", $mov->getVideoCodec()); - printf("get video bit rate = %d\n", $mov->getVideoBitRate()); - printf("get pixel format = %s\n", $mov->getPixelFormat()); - printf("get pixel aspect ratio = %s\n", $mov->getPixelAspectRatio()); - $frame = $mov->getFrame(10); - printf("get frame = %s\n", is_object($frame) ? 'true' : 'false'); - printf(" get frame number = %d\n", $mov->getFrameNumber()); - printf(" get frame width = %d\n", $frame->getWidth()); - printf(" get frame height = %d\n", $frame->getHeight()); - } - echo "\n--------------------\n\n"; -} - -if (php_sapi_name() != 'cli') { - echo ''; -} - -/* FUNCTIONS */ -function print_class_methods($class) { - echo "\nMethods available in class '$class':\n"; - $methods = get_class_methods($class); - if (is_array($methods)) { - foreach($methods as $method) { - echo $method . "\n"; - } - } else { - echo "No Methods Defined\n"; - } -} - -function getDirFiles($dirPath) -{ - if ($handle = opendir($dirPath)) - { - while (false !== ($file = readdir($handle))) { - $fullpath = $dirPath . '/' . $file; - if (!is_dir($fullpath) && $file != "CVS" && $file != "." && $file != "..") - $filesArr[] = trim($fullpath); - } - closedir($handle); - } - - return $filesArr; -} - - -?> diff --git a/ffmpeg-php/tests/getAudioBitRate.phpt b/ffmpeg-php/tests/getAudioBitRate.phpt deleted file mode 100644 index 272c116..0000000 --- a/ffmpeg-php/tests/getAudioBitRate.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getAudioBitRate test ---SKIPIF-- - ---FILE-- -getAudioBitRate()); -?> ---EXPECT-- -ffmpeg getAudioBitRate(): 32000 diff --git a/ffmpeg-php/tests/getAudioChannels.phpt b/ffmpeg-php/tests/getAudioChannels.phpt deleted file mode 100644 index 13bf89c..0000000 --- a/ffmpeg-php/tests/getAudioChannels.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getAudioChannels test ---SKIPIF-- - ---FILE-- -getAudioChannels()); -?> ---EXPECT-- -ffmpeg getAudioChannels(): 1 diff --git a/ffmpeg-php/tests/getAudioCodec.phpt b/ffmpeg-php/tests/getAudioCodec.phpt deleted file mode 100644 index 8e6c841..0000000 --- a/ffmpeg-php/tests/getAudioCodec.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getAudioCodec test ---SKIPIF-- - ---FILE-- -getAudioCodec()); -?> ---EXPECT-- -ffmpeg getAudioCodec(): mp2 diff --git a/ffmpeg-php/tests/getAudioSampleRate.phpt b/ffmpeg-php/tests/getAudioSampleRate.phpt deleted file mode 100644 index eba5bab..0000000 --- a/ffmpeg-php/tests/getAudioSampleRate.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getAudioSampleRate test ---SKIPIF-- - ---FILE-- -getAudioSampleRate()); -?> ---EXPECT-- -ffmpeg getAudioSampleRate(): 32000 diff --git a/ffmpeg-php/tests/getAudioStreamId.phpt b/ffmpeg-php/tests/getAudioStreamId.phpt deleted file mode 100644 index d2b1efb..0000000 --- a/ffmpeg-php/tests/getAudioStreamId.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getAudioStreamId test ---SKIPIF-- - ---FILE-- -getAudioStreamId()); -?> ---EXPECT-- -ffmpeg getAudioStreamId(): 0 diff --git a/ffmpeg-php/tests/getBitRate.phpt b/ffmpeg-php/tests/getBitRate.phpt deleted file mode 100644 index bfb9be3..0000000 --- a/ffmpeg-php/tests/getBitRate.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getBitRate test ---SKIPIF-- - ---FILE-- -getBitRate()); -?> ---EXPECT-- -ffmpeg getBitRate(): 183948 diff --git a/ffmpeg-php/tests/getDuration.phpt b/ffmpeg-php/tests/getDuration.phpt deleted file mode 100644 index f0d59e9..0000000 --- a/ffmpeg-php/tests/getDuration.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getDuration test ---SKIPIF-- - ---FILE-- -getDuration()); -?> ---EXPECT-- -ffmpeg getDuration(): 9.60 diff --git a/ffmpeg-php/tests/getFileName.phpt b/ffmpeg-php/tests/getFileName.phpt deleted file mode 100644 index df3add3..0000000 --- a/ffmpeg-php/tests/getFileName.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getFileName test ---SKIPIF-- - ---FILE-- -getFileName()); -?> ---EXPECTREGEX-- -ffmpeg getFileName\(\): .*\/robot.avi diff --git a/ffmpeg-php/tests/getFrame.phpt b/ffmpeg-php/tests/getFrame.phpt deleted file mode 100644 index 6a54338..0000000 --- a/ffmpeg-php/tests/getFrame.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -ffmpeg getFrame test ---SKIPIF-- - ---FILE-- -getFrame($frame); -if ($ff_frame) { - $gd_image = $ff_frame->toGDImage(); - if ($gd_image) { - imagepng($gd_image, $img); - imagedestroy($gd_image); - // generate md5 of file (NOTE: different versions of ffmpeg may produce different - // md5 hashes since resampling has been changed slightly due to a fix. Need to - // use EXPECTREX to test for both md5 possibilities. - printf("ffmpeg getFrame(): md5 = %s\n", md5(file_get_contents($img))); - unlink($img); - } -} -?> ---EXPECT-- -ffmpeg getFrame(): md5 = 8c9cbc1183504e1d1fee262e83775e01 diff --git a/ffmpeg-php/tests/getFrameCount.phpt b/ffmpeg-php/tests/getFrameCount.phpt deleted file mode 100644 index 9acd902..0000000 --- a/ffmpeg-php/tests/getFrameCount.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getFrameCount test ---SKIPIF-- - ---FILE-- -getFrameCount()); -?> ---EXPECT-- -ffmpeg getFrameCount(): 240 diff --git a/ffmpeg-php/tests/getFrameHeight.phpt b/ffmpeg-php/tests/getFrameHeight.phpt deleted file mode 100644 index 4e1c15c..0000000 --- a/ffmpeg-php/tests/getFrameHeight.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getFrameHeight test ---SKIPIF-- - ---FILE-- -getFrameHeight()); -?> ---EXPECT-- -ffmpeg getFrameHeight(): 112 diff --git a/ffmpeg-php/tests/getFrameNumber.phpt b/ffmpeg-php/tests/getFrameNumber.phpt deleted file mode 100644 index 6b9014e..0000000 --- a/ffmpeg-php/tests/getFrameNumber.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -ffmpeg getFrameNumber test ---SKIPIF-- - ---FILE-- -getFrame(5); -printf("ffmpeg getFrameNumber(): %d\n", $mov->getFrameNumber()); -?> ---EXPECT-- -ffmpeg getFrameNumber(): 5 diff --git a/ffmpeg-php/tests/getFrameRate.phpt b/ffmpeg-php/tests/getFrameRate.phpt deleted file mode 100644 index 6b800bb..0000000 --- a/ffmpeg-php/tests/getFrameRate.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getFrameRate test ---SKIPIF-- - ---FILE-- -getFrameRate()); -?> ---EXPECT-- -ffmpeg getFrameRate(): 25.00 diff --git a/ffmpeg-php/tests/getFrameWidth.phpt b/ffmpeg-php/tests/getFrameWidth.phpt deleted file mode 100644 index 175a246..0000000 --- a/ffmpeg-php/tests/getFrameWidth.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getFrameWidth test ---SKIPIF-- - ---FILE-- -getFrameWidth()); -?> ---EXPECT-- -ffmpeg getFrameWidth(): 160 diff --git a/ffmpeg-php/tests/getFramesBackwards.phpt b/ffmpeg-php/tests/getFramesBackwards.phpt deleted file mode 100644 index 0426988..0000000 --- a/ffmpeg-php/tests/getFramesBackwards.phpt +++ /dev/null @@ -1,264 +0,0 @@ ---TEST-- -ffmpeg getFrame backwards test ---SKIPIF-- - ---FILE-- -getFrameCount(); -for($i = $framecount; $i > 0; $i--) { - $img = sprintf("%s/test-%04d.png", dirname(__FILE__), $i); - $frame = $mov->getFrame($i); - $image = $frame->toGDImage(); - imagepng($image, $img); - printf("ffmpeg getFramesBackward($i): md5 = %s\n", md5(file_get_contents($img))); - imagedestroy($image); - unlink($img); -} -?> ---EXPECT-- -ffmpeg getFramesBackward(240): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFramesBackward(239): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFramesBackward(238): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFramesBackward(237): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFramesBackward(236): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFramesBackward(235): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFramesBackward(234): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFramesBackward(233): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFramesBackward(232): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFramesBackward(231): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFramesBackward(230): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFramesBackward(229): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFramesBackward(228): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFramesBackward(227): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFramesBackward(226): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFramesBackward(225): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFramesBackward(224): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFramesBackward(223): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFramesBackward(222): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFramesBackward(221): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFramesBackward(220): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFramesBackward(219): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFramesBackward(218): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFramesBackward(217): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFramesBackward(216): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFramesBackward(215): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFramesBackward(214): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFramesBackward(213): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFramesBackward(212): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFramesBackward(211): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFramesBackward(210): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFramesBackward(209): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFramesBackward(208): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFramesBackward(207): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFramesBackward(206): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFramesBackward(205): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFramesBackward(204): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFramesBackward(203): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFramesBackward(202): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFramesBackward(201): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFramesBackward(200): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFramesBackward(199): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFramesBackward(198): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFramesBackward(197): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFramesBackward(196): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFramesBackward(195): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFramesBackward(194): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFramesBackward(193): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFramesBackward(192): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFramesBackward(191): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFramesBackward(190): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFramesBackward(189): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFramesBackward(188): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFramesBackward(187): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFramesBackward(186): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFramesBackward(185): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFramesBackward(184): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFramesBackward(183): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFramesBackward(182): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFramesBackward(181): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFramesBackward(180): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFramesBackward(179): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFramesBackward(178): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFramesBackward(177): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFramesBackward(176): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFramesBackward(175): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFramesBackward(174): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFramesBackward(173): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFramesBackward(172): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFramesBackward(171): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFramesBackward(170): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFramesBackward(169): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFramesBackward(168): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFramesBackward(167): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFramesBackward(166): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFramesBackward(165): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFramesBackward(164): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFramesBackward(163): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFramesBackward(162): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFramesBackward(161): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFramesBackward(160): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFramesBackward(159): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFramesBackward(158): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFramesBackward(157): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFramesBackward(156): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFramesBackward(155): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFramesBackward(154): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFramesBackward(153): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFramesBackward(152): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFramesBackward(151): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFramesBackward(150): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFramesBackward(149): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFramesBackward(148): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFramesBackward(147): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFramesBackward(146): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFramesBackward(145): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFramesBackward(144): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFramesBackward(143): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFramesBackward(142): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFramesBackward(141): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFramesBackward(140): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFramesBackward(139): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFramesBackward(138): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFramesBackward(137): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFramesBackward(136): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFramesBackward(135): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFramesBackward(134): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFramesBackward(133): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFramesBackward(132): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFramesBackward(131): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFramesBackward(130): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFramesBackward(129): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFramesBackward(128): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFramesBackward(127): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFramesBackward(126): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFramesBackward(125): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFramesBackward(124): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFramesBackward(123): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFramesBackward(122): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFramesBackward(121): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFramesBackward(120): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFramesBackward(119): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFramesBackward(118): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFramesBackward(117): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFramesBackward(116): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFramesBackward(115): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFramesBackward(114): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFramesBackward(113): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFramesBackward(112): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFramesBackward(111): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFramesBackward(110): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFramesBackward(109): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFramesBackward(108): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFramesBackward(107): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFramesBackward(106): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFramesBackward(105): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFramesBackward(104): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFramesBackward(103): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFramesBackward(102): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFramesBackward(101): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFramesBackward(100): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFramesBackward(99): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFramesBackward(98): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFramesBackward(97): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFramesBackward(96): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFramesBackward(95): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFramesBackward(94): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFramesBackward(93): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFramesBackward(92): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFramesBackward(91): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFramesBackward(90): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFramesBackward(89): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFramesBackward(88): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFramesBackward(87): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFramesBackward(86): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFramesBackward(85): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFramesBackward(84): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFramesBackward(83): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFramesBackward(82): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFramesBackward(81): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFramesBackward(80): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFramesBackward(79): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFramesBackward(78): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFramesBackward(77): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFramesBackward(76): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFramesBackward(75): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFramesBackward(74): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFramesBackward(73): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFramesBackward(72): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFramesBackward(71): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFramesBackward(70): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFramesBackward(69): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFramesBackward(68): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFramesBackward(67): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFramesBackward(66): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFramesBackward(65): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFramesBackward(64): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFramesBackward(63): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFramesBackward(62): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFramesBackward(61): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFramesBackward(60): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFramesBackward(59): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFramesBackward(58): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFramesBackward(57): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFramesBackward(56): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFramesBackward(55): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFramesBackward(54): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFramesBackward(53): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFramesBackward(52): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFramesBackward(51): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFramesBackward(50): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFramesBackward(49): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFramesBackward(48): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFramesBackward(47): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFramesBackward(46): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFramesBackward(45): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFramesBackward(44): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFramesBackward(43): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFramesBackward(42): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFramesBackward(41): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFramesBackward(40): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFramesBackward(39): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFramesBackward(38): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFramesBackward(37): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFramesBackward(36): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFramesBackward(35): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFramesBackward(34): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFramesBackward(33): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFramesBackward(32): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFramesBackward(31): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFramesBackward(30): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFramesBackward(29): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFramesBackward(28): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFramesBackward(27): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFramesBackward(26): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFramesBackward(25): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFramesBackward(24): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFramesBackward(23): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFramesBackward(22): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFramesBackward(21): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFramesBackward(20): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFramesBackward(19): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFramesBackward(18): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFramesBackward(17): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFramesBackward(16): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFramesBackward(15): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFramesBackward(14): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFramesBackward(13): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFramesBackward(12): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFramesBackward(11): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFramesBackward(10): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFramesBackward(9): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFramesBackward(8): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFramesBackward(7): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFramesBackward(6): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFramesBackward(5): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFramesBackward(4): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFramesBackward(3): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFramesBackward(2): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFramesBackward(1): md5 = abdf9f281de68cef4b77a5a7a899b60a diff --git a/ffmpeg-php/tests/getFramesForward.phpt b/ffmpeg-php/tests/getFramesForward.phpt deleted file mode 100644 index 9fc2233..0000000 --- a/ffmpeg-php/tests/getFramesForward.phpt +++ /dev/null @@ -1,264 +0,0 @@ ---TEST-- -ffmpeg getFrames forward test ---SKIPIF-- - ---FILE-- -getFrameCount(); -for($i = 1; $i <= $framecount; $i++) { - $img = sprintf("%s/test-%04d.png", dirname(__FILE__), $i); - $frame = $mov->getFrame($i); - $image = $frame->toGDImage(); - imagepng($image, $img); - printf("ffmpeg getFramesForward($i): md5 = %s\n", md5(file_get_contents($img))); - imagedestroy($image); - unlink($img); -} -?> ---EXPECT-- -ffmpeg getFramesForward(1): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFramesForward(2): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFramesForward(3): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFramesForward(4): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFramesForward(5): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFramesForward(6): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFramesForward(7): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFramesForward(8): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFramesForward(9): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFramesForward(10): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFramesForward(11): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFramesForward(12): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFramesForward(13): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFramesForward(14): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFramesForward(15): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFramesForward(16): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFramesForward(17): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFramesForward(18): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFramesForward(19): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFramesForward(20): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFramesForward(21): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFramesForward(22): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFramesForward(23): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFramesForward(24): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFramesForward(25): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFramesForward(26): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFramesForward(27): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFramesForward(28): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFramesForward(29): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFramesForward(30): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFramesForward(31): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFramesForward(32): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFramesForward(33): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFramesForward(34): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFramesForward(35): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFramesForward(36): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFramesForward(37): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFramesForward(38): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFramesForward(39): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFramesForward(40): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFramesForward(41): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFramesForward(42): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFramesForward(43): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFramesForward(44): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFramesForward(45): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFramesForward(46): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFramesForward(47): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFramesForward(48): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFramesForward(49): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFramesForward(50): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFramesForward(51): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFramesForward(52): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFramesForward(53): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFramesForward(54): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFramesForward(55): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFramesForward(56): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFramesForward(57): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFramesForward(58): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFramesForward(59): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFramesForward(60): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFramesForward(61): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFramesForward(62): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFramesForward(63): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFramesForward(64): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFramesForward(65): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFramesForward(66): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFramesForward(67): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFramesForward(68): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFramesForward(69): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFramesForward(70): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFramesForward(71): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFramesForward(72): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFramesForward(73): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFramesForward(74): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFramesForward(75): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFramesForward(76): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFramesForward(77): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFramesForward(78): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFramesForward(79): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFramesForward(80): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFramesForward(81): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFramesForward(82): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFramesForward(83): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFramesForward(84): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFramesForward(85): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFramesForward(86): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFramesForward(87): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFramesForward(88): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFramesForward(89): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFramesForward(90): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFramesForward(91): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFramesForward(92): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFramesForward(93): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFramesForward(94): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFramesForward(95): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFramesForward(96): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFramesForward(97): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFramesForward(98): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFramesForward(99): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFramesForward(100): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFramesForward(101): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFramesForward(102): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFramesForward(103): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFramesForward(104): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFramesForward(105): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFramesForward(106): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFramesForward(107): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFramesForward(108): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFramesForward(109): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFramesForward(110): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFramesForward(111): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFramesForward(112): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFramesForward(113): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFramesForward(114): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFramesForward(115): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFramesForward(116): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFramesForward(117): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFramesForward(118): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFramesForward(119): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFramesForward(120): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFramesForward(121): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFramesForward(122): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFramesForward(123): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFramesForward(124): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFramesForward(125): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFramesForward(126): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFramesForward(127): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFramesForward(128): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFramesForward(129): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFramesForward(130): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFramesForward(131): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFramesForward(132): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFramesForward(133): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFramesForward(134): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFramesForward(135): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFramesForward(136): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFramesForward(137): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFramesForward(138): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFramesForward(139): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFramesForward(140): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFramesForward(141): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFramesForward(142): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFramesForward(143): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFramesForward(144): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFramesForward(145): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFramesForward(146): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFramesForward(147): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFramesForward(148): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFramesForward(149): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFramesForward(150): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFramesForward(151): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFramesForward(152): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFramesForward(153): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFramesForward(154): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFramesForward(155): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFramesForward(156): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFramesForward(157): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFramesForward(158): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFramesForward(159): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFramesForward(160): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFramesForward(161): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFramesForward(162): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFramesForward(163): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFramesForward(164): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFramesForward(165): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFramesForward(166): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFramesForward(167): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFramesForward(168): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFramesForward(169): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFramesForward(170): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFramesForward(171): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFramesForward(172): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFramesForward(173): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFramesForward(174): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFramesForward(175): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFramesForward(176): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFramesForward(177): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFramesForward(178): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFramesForward(179): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFramesForward(180): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFramesForward(181): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFramesForward(182): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFramesForward(183): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFramesForward(184): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFramesForward(185): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFramesForward(186): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFramesForward(187): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFramesForward(188): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFramesForward(189): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFramesForward(190): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFramesForward(191): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFramesForward(192): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFramesForward(193): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFramesForward(194): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFramesForward(195): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFramesForward(196): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFramesForward(197): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFramesForward(198): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFramesForward(199): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFramesForward(200): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFramesForward(201): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFramesForward(202): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFramesForward(203): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFramesForward(204): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFramesForward(205): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFramesForward(206): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFramesForward(207): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFramesForward(208): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFramesForward(209): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFramesForward(210): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFramesForward(211): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFramesForward(212): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFramesForward(213): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFramesForward(214): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFramesForward(215): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFramesForward(216): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFramesForward(217): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFramesForward(218): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFramesForward(219): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFramesForward(220): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFramesForward(221): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFramesForward(222): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFramesForward(223): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFramesForward(224): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFramesForward(225): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFramesForward(226): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFramesForward(227): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFramesForward(228): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFramesForward(229): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFramesForward(230): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFramesForward(231): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFramesForward(232): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFramesForward(233): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFramesForward(234): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFramesForward(235): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFramesForward(236): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFramesForward(237): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFramesForward(238): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFramesForward(239): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFramesForward(240): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d diff --git a/ffmpeg-php/tests/getFramesForwardPassedEnd.phpt b/ffmpeg-php/tests/getFramesForwardPassedEnd.phpt deleted file mode 100644 index 093a0d3..0000000 --- a/ffmpeg-php/tests/getFramesForwardPassedEnd.phpt +++ /dev/null @@ -1,269 +0,0 @@ ---TEST-- -ffmpeg getFrames forward test ---SKIPIF-- - ---FILE-- -getFrameCount(); -for($i = 1; $i <= $framecount + 1; $i++) { - $img = sprintf("%s/test-%04d.png", dirname(__FILE__), $i); - $frame = $mov->getFrame($i); - if ($frame == false) { - break; - } - $image = $frame->toGDImage(); - imagepng($image, $img); - printf("ffmpeg getFrame($i): md5 = %s\n", md5(file_get_contents($img))); - imagedestroy($image); - unlink($img); -} -?> ---EXPECT-- -ffmpeg getFrame(1): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(2): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(3): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(4): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(5): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(6): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(7): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(8): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(9): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(10): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(11): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(12): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(13): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(14): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(15): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(16): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(17): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(18): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(19): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(20): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(21): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(22): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(23): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(24): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(25): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(26): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(27): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(28): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(29): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(30): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(31): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(32): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(33): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(34): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(35): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(36): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(37): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(38): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(39): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(40): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(41): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(42): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(43): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(44): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(45): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(46): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(47): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(48): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(49): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(50): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(51): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(52): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(53): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(54): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(55): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(56): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(57): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(58): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(59): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(60): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(61): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(62): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(63): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(64): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(65): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(66): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(67): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(68): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(69): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(70): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(71): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(72): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(73): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(74): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(75): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(76): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(77): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(78): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(79): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(80): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(81): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(82): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(83): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(84): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(85): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(86): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(87): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(88): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(89): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(90): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(91): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(92): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(93): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(94): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(95): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(96): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(97): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(98): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(99): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(100): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(101): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(102): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(103): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(104): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(105): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(106): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(107): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(108): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(109): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(110): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(111): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(112): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(113): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(114): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(115): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(116): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(117): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(118): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(119): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(120): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(121): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(122): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(123): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(124): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(125): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(126): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(127): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(128): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(129): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(130): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(131): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(132): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(133): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(134): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(135): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(136): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(137): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(138): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(139): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(140): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(141): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(142): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(143): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(144): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(145): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(146): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(147): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(148): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(149): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(150): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(151): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(152): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(153): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(154): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(155): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(156): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(157): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(158): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(159): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(160): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(161): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(162): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(163): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(164): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(165): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(166): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(167): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(168): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(169): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(170): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(171): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(172): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(173): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(174): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(175): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(176): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(177): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(178): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(179): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(180): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(181): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(182): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(183): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(184): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(185): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(186): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(187): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(188): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(189): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(190): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(191): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(192): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(193): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(194): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(195): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(196): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(197): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(198): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(199): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(200): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(201): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(202): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(203): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(204): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(205): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(206): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(207): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(208): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(209): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(210): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(211): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(212): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(213): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(214): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(215): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(216): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(217): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(218): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(219): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(220): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(221): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(222): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(223): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(224): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(225): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(226): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(227): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(228): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(229): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(230): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(231): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(232): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(233): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(234): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(235): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(236): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(237): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(238): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(239): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(240): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(241): md5 = c3fca01d3ba84b05c18574615858e613 - diff --git a/ffmpeg-php/tests/getFramesNoArg.phpt b/ffmpeg-php/tests/getFramesNoArg.phpt deleted file mode 100644 index 93d11ca..0000000 --- a/ffmpeg-php/tests/getFramesNoArg.phpt +++ /dev/null @@ -1,267 +0,0 @@ ---TEST-- -ffmpeg getFramesNoArg test ---SKIPIF-- - ---FILE-- -getFrame()) != false) { - $i++; - $filename = $img . $i . '.png'; - $gd_image = $frame->toGDImage(); - imagepng($gd_image, $filename); - printf("ffmpeg getFrame($i): md5 = %s\n", md5(file_get_contents($filename))); - imagedestroy($gd_image); - unlink($filename); -} -?> ---EXPECT-- -ffmpeg getFrame(1): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(2): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(3): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(4): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(5): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(6): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(7): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(8): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(9): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(10): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(11): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(12): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(13): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(14): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(15): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(16): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(17): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(18): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(19): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(20): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(21): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(22): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(23): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(24): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(25): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(26): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(27): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(28): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(29): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(30): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(31): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(32): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(33): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(34): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(35): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(36): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(37): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(38): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(39): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(40): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(41): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(42): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(43): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(44): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(45): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(46): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(47): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(48): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(49): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(50): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(51): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(52): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(53): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(54): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(55): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(56): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(57): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(58): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(59): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(60): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(61): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(62): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(63): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(64): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(65): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(66): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(67): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(68): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(69): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(70): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(71): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(72): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(73): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(74): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(75): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(76): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(77): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(78): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(79): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(80): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(81): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(82): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(83): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(84): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(85): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(86): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(87): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(88): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(89): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(90): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(91): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(92): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(93): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(94): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(95): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(96): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(97): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(98): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(99): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(100): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(101): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(102): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(103): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(104): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(105): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(106): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(107): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(108): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(109): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(110): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(111): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(112): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(113): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(114): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(115): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(116): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(117): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(118): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(119): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(120): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(121): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(122): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(123): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(124): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(125): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(126): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(127): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(128): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(129): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(130): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(131): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(132): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(133): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(134): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(135): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(136): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(137): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(138): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(139): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(140): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(141): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(142): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(143): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(144): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(145): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(146): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(147): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(148): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(149): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(150): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(151): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(152): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(153): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(154): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(155): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(156): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(157): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(158): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(159): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(160): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(161): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(162): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(163): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(164): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(165): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(166): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(167): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(168): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(169): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(170): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(171): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(172): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(173): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(174): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(175): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(176): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(177): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(178): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(179): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(180): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(181): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(182): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(183): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(184): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(185): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(186): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(187): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(188): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(189): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(190): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(191): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(192): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(193): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(194): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(195): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(196): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(197): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(198): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(199): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(200): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(201): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(202): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(203): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(204): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(205): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(206): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(207): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(208): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(209): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(210): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(211): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(212): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(213): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(214): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(215): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(216): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(217): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(218): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(219): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(220): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(221): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(222): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(223): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(224): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(225): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(226): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(227): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(228): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(229): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(230): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(231): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(232): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(233): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(234): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(235): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(236): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(237): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(238): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(239): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(240): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(241): md5 = c3fca01d3ba84b05c18574615858e613 -ffmpeg getFrame(242): md5 = c3fca01d3ba84b05c18574615858e613 diff --git a/ffmpeg-php/tests/getID3Info.phpt b/ffmpeg-php/tests/getID3Info.phpt deleted file mode 100644 index c9a8c24..0000000 --- a/ffmpeg-php/tests/getID3Info.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -ffmpeg getID3Info() test ---SKIPIF-- - ---FILE-- -getTitle()); -printf("ffmpeg getArtist(): %s\n", $mov->getArtist()); -printf("ffmpeg getAlbum(): %s\n", $mov->getAlbum()); -printf("ffmpeg getGenre(): %s\n", $mov->getGenre()); -printf("ffmpeg getTrackNumber(): %s\n", $mov->getTrackNumber()); -printf("ffmpeg getYear(): %s\n", $mov->getYear()); - -?> ---EXPECT-- -ffmpeg getTitle(): Test mp3 -ffmpeg getArtist(): Alexander Thomas -ffmpeg getAlbum(): MP3 test files (http://www.dr-lex.be/software/testsounds.html#Tones) -ffmpeg getGenre(): (37) -ffmpeg getTrackNumber(): 3 -ffmpeg getYear(): 2008 diff --git a/ffmpeg-php/tests/getNextKeyFrame.phpt b/ffmpeg-php/tests/getNextKeyFrame.phpt deleted file mode 100644 index 7848e39..0000000 --- a/ffmpeg-php/tests/getNextKeyFrame.phpt +++ /dev/null @@ -1,266 +0,0 @@ ---TEST-- -ffmpeg get key frames test ---SKIPIF-- - ---FILE-- -getNextKeyFrame()) != false) { - $i = $mov->getFrameNumber(); - $filename = $img . $i . '.png'; - $gd_image = $frame->toGDImage(); - imagepng($gd_image, $filename); - printf("ffmpeg getFrame($i): md5 = %s\n", md5(file_get_contents($filename))); - imagedestroy($gd_image); - unlink($filename); -} -?> ---EXPECT-- -ffmpeg getFrame(1): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(2): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(3): md5 = abdf9f281de68cef4b77a5a7a899b60a -ffmpeg getFrame(4): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(5): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(6): md5 = 9770f3afe55297ea35c9f06a0e4334ea -ffmpeg getFrame(7): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(8): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(9): md5 = 157cf8c54851ee90bda8b2398b077c28 -ffmpeg getFrame(10): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(11): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(12): md5 = 966a1fb1d649d8fdc6552ce6fa0e735f -ffmpeg getFrame(13): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(14): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(15): md5 = 5415f831017e32afa73e5ceb32344f4d -ffmpeg getFrame(16): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(17): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(18): md5 = 337873cd3a4b8529dae4da4aac38874c -ffmpeg getFrame(19): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(20): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(21): md5 = 3411d97fd52b27b7105a4cf91a7b181e -ffmpeg getFrame(22): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(23): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(24): md5 = 74c553e7c88fd2479610cd2093d75717 -ffmpeg getFrame(25): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(26): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(27): md5 = c9ec47e51edb4a58c1c76a2202d7147f -ffmpeg getFrame(28): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(29): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(30): md5 = 0f54b4e8a9e3cbbc6c5e1729f4793b2f -ffmpeg getFrame(31): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(32): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(33): md5 = 30f0dff87230a9f3b1ebdc08b40aa0a7 -ffmpeg getFrame(34): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(35): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(36): md5 = f614e07399921150044dfdaf880afa17 -ffmpeg getFrame(37): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(38): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(39): md5 = ae68f48c14a76e4dc2f9c7f2183c7787 -ffmpeg getFrame(40): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(41): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(42): md5 = b8ae52b0bd25ff1ccddfffd61c2aee5a -ffmpeg getFrame(43): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(44): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(45): md5 = 1560e32dc970140780155a3b9b8a5458 -ffmpeg getFrame(46): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(47): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(48): md5 = 9d6241b89b0320d045c81564ae392df1 -ffmpeg getFrame(49): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(50): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(51): md5 = ac35fe74cc8150970d6b8d6b6615ee7d -ffmpeg getFrame(52): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(53): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(54): md5 = e256491e34893b935d9a3839536d2587 -ffmpeg getFrame(55): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(56): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(57): md5 = 1c72b33fd6f829b293a83acd9dd6ba3e -ffmpeg getFrame(58): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(59): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(60): md5 = 954c1013975c1fc29ab8bbaf9208069a -ffmpeg getFrame(61): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(62): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(63): md5 = 86d1330ec92bb2c672db8cfacef7c128 -ffmpeg getFrame(64): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(65): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(66): md5 = 3b8248dcafbc02ecab8f5a3065e61f03 -ffmpeg getFrame(67): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(68): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(69): md5 = db77eae1c1395ba1c794ae1281d68868 -ffmpeg getFrame(70): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(71): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(72): md5 = afe384b15e07ea544fa7a1cdada288c0 -ffmpeg getFrame(73): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(74): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(75): md5 = 8c9cbc1183504e1d1fee262e83775e01 -ffmpeg getFrame(76): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(77): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(78): md5 = d502f1afe81ec69de3222d3b56b3d516 -ffmpeg getFrame(79): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(80): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(81): md5 = 8004f62b065a0d55150220972821be96 -ffmpeg getFrame(82): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(83): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(84): md5 = 92ecabfab41f2715a05f3847e2484b60 -ffmpeg getFrame(85): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(86): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(87): md5 = ceafeaf93812d8f5fd48f6fa242d5e36 -ffmpeg getFrame(88): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(89): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(90): md5 = 41b5423e725b29fdacc5ee40faa4776c -ffmpeg getFrame(91): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(92): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(93): md5 = afa2f0bab3ba2b34806b2a52aea98bce -ffmpeg getFrame(94): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(95): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(96): md5 = c8ed36df36fb8cea156212a5d5952d33 -ffmpeg getFrame(97): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(98): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(99): md5 = c97ea8a480b98c52f8b726b811f9714d -ffmpeg getFrame(100): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(101): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(102): md5 = a98e967bbda4b6dcaa19fd52d9fdef12 -ffmpeg getFrame(103): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(104): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(105): md5 = 395b50b5c8615cdb4b905aa0b3b2e669 -ffmpeg getFrame(106): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(107): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(108): md5 = 86f50526473282524be5c092f77950a5 -ffmpeg getFrame(109): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(110): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(111): md5 = 9e5e0b70bfc1c90f2c5092428bc384ee -ffmpeg getFrame(112): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(113): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(114): md5 = 5f9109436658f422ec1841247acf835e -ffmpeg getFrame(115): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(116): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(117): md5 = 80e13931ccc6ace3a5a7ae256e048a61 -ffmpeg getFrame(118): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(119): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(120): md5 = 21f287b5f3334a7aaed0aeeb55230621 -ffmpeg getFrame(121): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(122): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(123): md5 = 22caa03aaa35e0aed2f0a3d4a3375b24 -ffmpeg getFrame(124): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(125): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(126): md5 = 36cbf250ecf8c5a5538bd0a5f2eb9333 -ffmpeg getFrame(127): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(128): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(129): md5 = ffdc385768b0b1fcbb9908c9c9bffe21 -ffmpeg getFrame(130): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(131): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(132): md5 = 3ead3c1a402a7e26ee248cd8f9c96647 -ffmpeg getFrame(133): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(134): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(135): md5 = 3445a37f0effaef1a9c4e788f5ce54e5 -ffmpeg getFrame(136): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(137): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(138): md5 = 948fd5fd379679006c2ca2ba3bc52048 -ffmpeg getFrame(139): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(140): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(141): md5 = 814b8a64a6a08093b3a81063bffffed4 -ffmpeg getFrame(142): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(143): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(144): md5 = 51a73cbaf315c9faf8263627455fd5d5 -ffmpeg getFrame(145): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(146): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(147): md5 = 31038504cc4c1e664de89c257b1fa1b0 -ffmpeg getFrame(148): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(149): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(150): md5 = c76afdadc9099d8bd173f0e08807ee3d -ffmpeg getFrame(151): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(152): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(153): md5 = cd42cff504053e23c5db378119a40b3f -ffmpeg getFrame(154): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(155): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(156): md5 = 7862bd022cc4e9c3976b2f4758e5cd30 -ffmpeg getFrame(157): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(158): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(159): md5 = 7dee4d143138fce530917488cc337c8c -ffmpeg getFrame(160): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(161): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(162): md5 = 254d01500e3ec7f6ae402747761c0a95 -ffmpeg getFrame(163): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(164): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(165): md5 = fe0cdb9314d1628af56e6c3662deb24f -ffmpeg getFrame(166): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(167): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(168): md5 = c790f8cc0f715ca0ec31845c9ef7397a -ffmpeg getFrame(169): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(170): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(171): md5 = bab883284018046ddfa2e638785615aa -ffmpeg getFrame(172): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(173): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(174): md5 = a469093f43c0fdd6016ee5ef932b7ca4 -ffmpeg getFrame(175): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(176): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(177): md5 = 50d636deb9cdca5c88842653d3e62463 -ffmpeg getFrame(178): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(179): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(180): md5 = 7def27ec8a2136e344b24b12337f3a0c -ffmpeg getFrame(181): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(182): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(183): md5 = 93bdda9b26422cf7791154d54667812e -ffmpeg getFrame(184): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(185): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(186): md5 = 965909c3829a19aa301ff7dc98f1ca90 -ffmpeg getFrame(187): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(188): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(189): md5 = a53b0c4d2c023f1019b3190b35216c60 -ffmpeg getFrame(190): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(191): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(192): md5 = b900f912fbe898801a4c8356638dcf54 -ffmpeg getFrame(193): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(194): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(195): md5 = 5221475c9ea8970258feb9dab1392049 -ffmpeg getFrame(196): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(197): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(198): md5 = 6851e0793856841f31acc6a5f704650c -ffmpeg getFrame(199): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(200): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(201): md5 = 35335bb3cbc1cb75aff8416a26df8f39 -ffmpeg getFrame(202): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(203): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(204): md5 = c9584d3d2c2480fb480953e9bc317cb0 -ffmpeg getFrame(205): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(206): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(207): md5 = 3081db2af3ff5bc76f938f9b80ec72bb -ffmpeg getFrame(208): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(209): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(210): md5 = 10230400f9cdb8a4785082ed133f4c40 -ffmpeg getFrame(211): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(212): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(213): md5 = ccc8aa4b659a072ef3e94005e982e197 -ffmpeg getFrame(214): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(215): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(216): md5 = 916130d3a9a0b5291dd80c3f905f3cfe -ffmpeg getFrame(217): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(218): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(219): md5 = c9b92c3b3043cadf83b634aaa9967af2 -ffmpeg getFrame(220): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(221): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(222): md5 = d60ad82118cc3d82d61380e8c1c35821 -ffmpeg getFrame(223): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(224): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(225): md5 = bb894534f0fbb93ae13effea4ae7778c -ffmpeg getFrame(226): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(227): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(228): md5 = 03fe855c91fbaabe9e260a23ca4fa6cd -ffmpeg getFrame(229): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(230): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(231): md5 = 92b0f153f17e6a387535ba873c245ef2 -ffmpeg getFrame(232): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(233): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(234): md5 = f513c73faf87cbfe1fff854d97f8f492 -ffmpeg getFrame(235): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(236): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(237): md5 = 972e660b84a02fb883809c93f1ffdbf8 -ffmpeg getFrame(238): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(239): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(240): md5 = 7e80bfd9c95b8f46e4ffcc1acacd478d -ffmpeg getFrame(241): md5 = c3fca01d3ba84b05c18574615858e613 -ffmpeg getFrame(242): md5 = c3fca01d3ba84b05c18574615858e613 diff --git a/ffmpeg-php/tests/getPTS.phpt b/ffmpeg-php/tests/getPTS.phpt deleted file mode 100644 index e75e1a0..0000000 --- a/ffmpeg-php/tests/getPTS.phpt +++ /dev/null @@ -1,259 +0,0 @@ ---TEST-- -ffmpeg getPTS test (Fixme: This test is no good with robot.avi) ---SKIPIF-- - ---FILE-- -getFrameCount(); -for($i = 1; $i <= $framecount; $i++) { - $frame = $mov->getFrame($i); - printf("ffmpeg getPresentationTimestamp($i): = %s\n", $frame->getPTS()); -} -?> ---EXPECT-- -ffmpeg getPresentationTimestamp(1): = -9223372036850 -ffmpeg getPresentationTimestamp(2): = -9223372036850 -ffmpeg getPresentationTimestamp(3): = 0.0268 -ffmpeg getPresentationTimestamp(4): = -9223372036850 -ffmpeg getPresentationTimestamp(5): = -9223372036850 -ffmpeg getPresentationTimestamp(6): = 0.0376 -ffmpeg getPresentationTimestamp(7): = -9223372036850 -ffmpeg getPresentationTimestamp(8): = -9223372036850 -ffmpeg getPresentationTimestamp(9): = 0.0484 -ffmpeg getPresentationTimestamp(10): = -9223372036850 -ffmpeg getPresentationTimestamp(11): = -9223372036850 -ffmpeg getPresentationTimestamp(12): = 0.0592 -ffmpeg getPresentationTimestamp(13): = -9223372036850 -ffmpeg getPresentationTimestamp(14): = -9223372036850 -ffmpeg getPresentationTimestamp(15): = 0.07 -ffmpeg getPresentationTimestamp(16): = -9223372036850 -ffmpeg getPresentationTimestamp(17): = -9223372036850 -ffmpeg getPresentationTimestamp(18): = 0.0808 -ffmpeg getPresentationTimestamp(19): = -9223372036850 -ffmpeg getPresentationTimestamp(20): = -9223372036850 -ffmpeg getPresentationTimestamp(21): = 0.0916 -ffmpeg getPresentationTimestamp(22): = -9223372036850 -ffmpeg getPresentationTimestamp(23): = -9223372036850 -ffmpeg getPresentationTimestamp(24): = 0.1024 -ffmpeg getPresentationTimestamp(25): = -9223372036850 -ffmpeg getPresentationTimestamp(26): = -9223372036850 -ffmpeg getPresentationTimestamp(27): = 0.1132 -ffmpeg getPresentationTimestamp(28): = -9223372036850 -ffmpeg getPresentationTimestamp(29): = -9223372036850 -ffmpeg getPresentationTimestamp(30): = 0.124 -ffmpeg getPresentationTimestamp(31): = -9223372036850 -ffmpeg getPresentationTimestamp(32): = -9223372036850 -ffmpeg getPresentationTimestamp(33): = 0.1348 -ffmpeg getPresentationTimestamp(34): = -9223372036850 -ffmpeg getPresentationTimestamp(35): = -9223372036850 -ffmpeg getPresentationTimestamp(36): = 0.1456 -ffmpeg getPresentationTimestamp(37): = -9223372036850 -ffmpeg getPresentationTimestamp(38): = -9223372036850 -ffmpeg getPresentationTimestamp(39): = 0.1564 -ffmpeg getPresentationTimestamp(40): = -9223372036850 -ffmpeg getPresentationTimestamp(41): = -9223372036850 -ffmpeg getPresentationTimestamp(42): = 0.1672 -ffmpeg getPresentationTimestamp(43): = -9223372036850 -ffmpeg getPresentationTimestamp(44): = -9223372036850 -ffmpeg getPresentationTimestamp(45): = 0.178 -ffmpeg getPresentationTimestamp(46): = -9223372036850 -ffmpeg getPresentationTimestamp(47): = -9223372036850 -ffmpeg getPresentationTimestamp(48): = 0.1888 -ffmpeg getPresentationTimestamp(49): = -9223372036850 -ffmpeg getPresentationTimestamp(50): = -9223372036850 -ffmpeg getPresentationTimestamp(51): = 0.1996 -ffmpeg getPresentationTimestamp(52): = -9223372036850 -ffmpeg getPresentationTimestamp(53): = -9223372036850 -ffmpeg getPresentationTimestamp(54): = 0.2104 -ffmpeg getPresentationTimestamp(55): = -9223372036850 -ffmpeg getPresentationTimestamp(56): = -9223372036850 -ffmpeg getPresentationTimestamp(57): = 0.2212 -ffmpeg getPresentationTimestamp(58): = -9223372036850 -ffmpeg getPresentationTimestamp(59): = -9223372036850 -ffmpeg getPresentationTimestamp(60): = 0.232 -ffmpeg getPresentationTimestamp(61): = -9223372036850 -ffmpeg getPresentationTimestamp(62): = -9223372036850 -ffmpeg getPresentationTimestamp(63): = 0.2428 -ffmpeg getPresentationTimestamp(64): = -9223372036850 -ffmpeg getPresentationTimestamp(65): = -9223372036850 -ffmpeg getPresentationTimestamp(66): = 0.2536 -ffmpeg getPresentationTimestamp(67): = -9223372036850 -ffmpeg getPresentationTimestamp(68): = -9223372036850 -ffmpeg getPresentationTimestamp(69): = 0.2644 -ffmpeg getPresentationTimestamp(70): = -9223372036850 -ffmpeg getPresentationTimestamp(71): = -9223372036850 -ffmpeg getPresentationTimestamp(72): = 0.2752 -ffmpeg getPresentationTimestamp(73): = -9223372036850 -ffmpeg getPresentationTimestamp(74): = -9223372036850 -ffmpeg getPresentationTimestamp(75): = 0.286 -ffmpeg getPresentationTimestamp(76): = -9223372036850 -ffmpeg getPresentationTimestamp(77): = -9223372036850 -ffmpeg getPresentationTimestamp(78): = 0.2968 -ffmpeg getPresentationTimestamp(79): = -9223372036850 -ffmpeg getPresentationTimestamp(80): = -9223372036850 -ffmpeg getPresentationTimestamp(81): = 0.3076 -ffmpeg getPresentationTimestamp(82): = -9223372036850 -ffmpeg getPresentationTimestamp(83): = -9223372036850 -ffmpeg getPresentationTimestamp(84): = 0.3184 -ffmpeg getPresentationTimestamp(85): = -9223372036850 -ffmpeg getPresentationTimestamp(86): = -9223372036850 -ffmpeg getPresentationTimestamp(87): = 0.3292 -ffmpeg getPresentationTimestamp(88): = -9223372036850 -ffmpeg getPresentationTimestamp(89): = -9223372036850 -ffmpeg getPresentationTimestamp(90): = 0.34 -ffmpeg getPresentationTimestamp(91): = -9223372036850 -ffmpeg getPresentationTimestamp(92): = -9223372036850 -ffmpeg getPresentationTimestamp(93): = 0.3508 -ffmpeg getPresentationTimestamp(94): = -9223372036850 -ffmpeg getPresentationTimestamp(95): = -9223372036850 -ffmpeg getPresentationTimestamp(96): = 0.3616 -ffmpeg getPresentationTimestamp(97): = -9223372036850 -ffmpeg getPresentationTimestamp(98): = -9223372036850 -ffmpeg getPresentationTimestamp(99): = 0.3724 -ffmpeg getPresentationTimestamp(100): = -9223372036850 -ffmpeg getPresentationTimestamp(101): = -9223372036850 -ffmpeg getPresentationTimestamp(102): = 0.3832 -ffmpeg getPresentationTimestamp(103): = -9223372036850 -ffmpeg getPresentationTimestamp(104): = -9223372036850 -ffmpeg getPresentationTimestamp(105): = 0.394 -ffmpeg getPresentationTimestamp(106): = -9223372036850 -ffmpeg getPresentationTimestamp(107): = -9223372036850 -ffmpeg getPresentationTimestamp(108): = 0.4048 -ffmpeg getPresentationTimestamp(109): = -9223372036850 -ffmpeg getPresentationTimestamp(110): = -9223372036850 -ffmpeg getPresentationTimestamp(111): = 0.4156 -ffmpeg getPresentationTimestamp(112): = -9223372036850 -ffmpeg getPresentationTimestamp(113): = -9223372036850 -ffmpeg getPresentationTimestamp(114): = 0.4264 -ffmpeg getPresentationTimestamp(115): = -9223372036850 -ffmpeg getPresentationTimestamp(116): = -9223372036850 -ffmpeg getPresentationTimestamp(117): = 0.4372 -ffmpeg getPresentationTimestamp(118): = -9223372036850 -ffmpeg getPresentationTimestamp(119): = -9223372036850 -ffmpeg getPresentationTimestamp(120): = 0.448 -ffmpeg getPresentationTimestamp(121): = -9223372036850 -ffmpeg getPresentationTimestamp(122): = -9223372036850 -ffmpeg getPresentationTimestamp(123): = 0.4588 -ffmpeg getPresentationTimestamp(124): = -9223372036850 -ffmpeg getPresentationTimestamp(125): = -9223372036850 -ffmpeg getPresentationTimestamp(126): = 0.4696 -ffmpeg getPresentationTimestamp(127): = -9223372036850 -ffmpeg getPresentationTimestamp(128): = -9223372036850 -ffmpeg getPresentationTimestamp(129): = 0.4804 -ffmpeg getPresentationTimestamp(130): = -9223372036850 -ffmpeg getPresentationTimestamp(131): = -9223372036850 -ffmpeg getPresentationTimestamp(132): = 0.4912 -ffmpeg getPresentationTimestamp(133): = -9223372036850 -ffmpeg getPresentationTimestamp(134): = -9223372036850 -ffmpeg getPresentationTimestamp(135): = 0.502 -ffmpeg getPresentationTimestamp(136): = -9223372036850 -ffmpeg getPresentationTimestamp(137): = -9223372036850 -ffmpeg getPresentationTimestamp(138): = 0.5128 -ffmpeg getPresentationTimestamp(139): = -9223372036850 -ffmpeg getPresentationTimestamp(140): = -9223372036850 -ffmpeg getPresentationTimestamp(141): = 0.5236 -ffmpeg getPresentationTimestamp(142): = -9223372036850 -ffmpeg getPresentationTimestamp(143): = -9223372036850 -ffmpeg getPresentationTimestamp(144): = 0.5344 -ffmpeg getPresentationTimestamp(145): = -9223372036850 -ffmpeg getPresentationTimestamp(146): = -9223372036850 -ffmpeg getPresentationTimestamp(147): = 0.5452 -ffmpeg getPresentationTimestamp(148): = -9223372036850 -ffmpeg getPresentationTimestamp(149): = -9223372036850 -ffmpeg getPresentationTimestamp(150): = 0.556 -ffmpeg getPresentationTimestamp(151): = -9223372036850 -ffmpeg getPresentationTimestamp(152): = -9223372036850 -ffmpeg getPresentationTimestamp(153): = 0.5668 -ffmpeg getPresentationTimestamp(154): = -9223372036850 -ffmpeg getPresentationTimestamp(155): = -9223372036850 -ffmpeg getPresentationTimestamp(156): = 0.5776 -ffmpeg getPresentationTimestamp(157): = -9223372036850 -ffmpeg getPresentationTimestamp(158): = -9223372036850 -ffmpeg getPresentationTimestamp(159): = 0.5884 -ffmpeg getPresentationTimestamp(160): = -9223372036850 -ffmpeg getPresentationTimestamp(161): = -9223372036850 -ffmpeg getPresentationTimestamp(162): = 0.5992 -ffmpeg getPresentationTimestamp(163): = -9223372036850 -ffmpeg getPresentationTimestamp(164): = -9223372036850 -ffmpeg getPresentationTimestamp(165): = 0.61 -ffmpeg getPresentationTimestamp(166): = -9223372036850 -ffmpeg getPresentationTimestamp(167): = -9223372036850 -ffmpeg getPresentationTimestamp(168): = 0.6208 -ffmpeg getPresentationTimestamp(169): = -9223372036850 -ffmpeg getPresentationTimestamp(170): = -9223372036850 -ffmpeg getPresentationTimestamp(171): = 0.6316 -ffmpeg getPresentationTimestamp(172): = -9223372036850 -ffmpeg getPresentationTimestamp(173): = -9223372036850 -ffmpeg getPresentationTimestamp(174): = 0.6424 -ffmpeg getPresentationTimestamp(175): = -9223372036850 -ffmpeg getPresentationTimestamp(176): = -9223372036850 -ffmpeg getPresentationTimestamp(177): = 0.6532 -ffmpeg getPresentationTimestamp(178): = -9223372036850 -ffmpeg getPresentationTimestamp(179): = -9223372036850 -ffmpeg getPresentationTimestamp(180): = 0.664 -ffmpeg getPresentationTimestamp(181): = -9223372036850 -ffmpeg getPresentationTimestamp(182): = -9223372036850 -ffmpeg getPresentationTimestamp(183): = 0.6748 -ffmpeg getPresentationTimestamp(184): = -9223372036850 -ffmpeg getPresentationTimestamp(185): = -9223372036850 -ffmpeg getPresentationTimestamp(186): = 0.6856 -ffmpeg getPresentationTimestamp(187): = -9223372036850 -ffmpeg getPresentationTimestamp(188): = -9223372036850 -ffmpeg getPresentationTimestamp(189): = 0.6964 -ffmpeg getPresentationTimestamp(190): = -9223372036850 -ffmpeg getPresentationTimestamp(191): = -9223372036850 -ffmpeg getPresentationTimestamp(192): = 0.7072 -ffmpeg getPresentationTimestamp(193): = -9223372036850 -ffmpeg getPresentationTimestamp(194): = -9223372036850 -ffmpeg getPresentationTimestamp(195): = 0.718 -ffmpeg getPresentationTimestamp(196): = -9223372036850 -ffmpeg getPresentationTimestamp(197): = -9223372036850 -ffmpeg getPresentationTimestamp(198): = 0.7288 -ffmpeg getPresentationTimestamp(199): = -9223372036850 -ffmpeg getPresentationTimestamp(200): = -9223372036850 -ffmpeg getPresentationTimestamp(201): = 0.7396 -ffmpeg getPresentationTimestamp(202): = -9223372036850 -ffmpeg getPresentationTimestamp(203): = -9223372036850 -ffmpeg getPresentationTimestamp(204): = 0.7504 -ffmpeg getPresentationTimestamp(205): = -9223372036850 -ffmpeg getPresentationTimestamp(206): = -9223372036850 -ffmpeg getPresentationTimestamp(207): = 0.7612 -ffmpeg getPresentationTimestamp(208): = -9223372036850 -ffmpeg getPresentationTimestamp(209): = -9223372036850 -ffmpeg getPresentationTimestamp(210): = 0.772 -ffmpeg getPresentationTimestamp(211): = -9223372036850 -ffmpeg getPresentationTimestamp(212): = -9223372036850 -ffmpeg getPresentationTimestamp(213): = 0.7828 -ffmpeg getPresentationTimestamp(214): = -9223372036850 -ffmpeg getPresentationTimestamp(215): = -9223372036850 -ffmpeg getPresentationTimestamp(216): = 0.7936 -ffmpeg getPresentationTimestamp(217): = -9223372036850 -ffmpeg getPresentationTimestamp(218): = -9223372036850 -ffmpeg getPresentationTimestamp(219): = 0.8044 -ffmpeg getPresentationTimestamp(220): = -9223372036850 -ffmpeg getPresentationTimestamp(221): = -9223372036850 -ffmpeg getPresentationTimestamp(222): = 0.8152 -ffmpeg getPresentationTimestamp(223): = -9223372036850 -ffmpeg getPresentationTimestamp(224): = -9223372036850 -ffmpeg getPresentationTimestamp(225): = 0.826 -ffmpeg getPresentationTimestamp(226): = -9223372036850 -ffmpeg getPresentationTimestamp(227): = -9223372036850 -ffmpeg getPresentationTimestamp(228): = 0.8368 -ffmpeg getPresentationTimestamp(229): = -9223372036850 -ffmpeg getPresentationTimestamp(230): = -9223372036850 -ffmpeg getPresentationTimestamp(231): = 0.8476 -ffmpeg getPresentationTimestamp(232): = -9223372036850 -ffmpeg getPresentationTimestamp(233): = -9223372036850 -ffmpeg getPresentationTimestamp(234): = 0.8584 -ffmpeg getPresentationTimestamp(235): = -9223372036850 -ffmpeg getPresentationTimestamp(236): = -9223372036850 -ffmpeg getPresentationTimestamp(237): = 0.8692 -ffmpeg getPresentationTimestamp(238): = -9223372036850 -ffmpeg getPresentationTimestamp(239): = -9223372036850 -ffmpeg getPresentationTimestamp(240): = 0.88 diff --git a/ffmpeg-php/tests/getPixelAspectRatio.phpt b/ffmpeg-php/tests/getPixelAspectRatio.phpt deleted file mode 100644 index 7e1df1a..0000000 --- a/ffmpeg-php/tests/getPixelAspectRatio.phpt +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -ffmpeg getPixelAspectRatio test ---SKIPIF-- - ---FILE-- -getPixelAspectRatio()); - -?> ---EXPECT-- -ffmpeg getPixelAspectRatio(): 1 diff --git a/ffmpeg-php/tests/getPixelFormat.phpt b/ffmpeg-php/tests/getPixelFormat.phpt deleted file mode 100644 index 31c6691..0000000 --- a/ffmpeg-php/tests/getPixelFormat.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getPixelFormat test ---SKIPIF-- - ---FILE-- -getPixelFormat()); -?> ---EXPECT-- -ffmpeg getPixelFormat(): yuv420p diff --git a/ffmpeg-php/tests/getVideoBitRate.phpt b/ffmpeg-php/tests/getVideoBitRate.phpt deleted file mode 100644 index 5c2f934..0000000 --- a/ffmpeg-php/tests/getVideoBitRate.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getVideoBitRate test ---SKIPIF-- - ---FILE-- -getVideoBitRate()); -?> ---EXPECT-- -ffmpeg getVideoBitRate(): 104857200 diff --git a/ffmpeg-php/tests/getVideoCodec.phpt b/ffmpeg-php/tests/getVideoCodec.phpt deleted file mode 100644 index 6e736de..0000000 --- a/ffmpeg-php/tests/getVideoCodec.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getVideoCodec test ---SKIPIF-- - ---FILE-- -getVideoCodec()); -?> ---EXPECT-- -ffmpeg getVideoCodec(): mpeg1video diff --git a/ffmpeg-php/tests/getVideoStreamId.phpt b/ffmpeg-php/tests/getVideoStreamId.phpt deleted file mode 100644 index 0bde9b6..0000000 --- a/ffmpeg-php/tests/getVideoStreamId.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg getVideoStreamId test ---SKIPIF-- - ---FILE-- -getVideoStreamId()); -?> ---EXPECT-- -ffmpeg getVideoStreamId(): 1 diff --git a/ffmpeg-php/tests/hasAudio.phpt b/ffmpeg-php/tests/hasAudio.phpt deleted file mode 100644 index 8f39702..0000000 --- a/ffmpeg-php/tests/hasAudio.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -ffmpeg hasAudio test ---SKIPIF-- - ---FILE-- -hasAudio() ? 'Yes' : 'No'); -?> ---EXPECT-- -ffmpeg hasAudio(): Yes diff --git a/ffmpeg-php/tests/isKeyFrame.phpt b/ffmpeg-php/tests/isKeyFrame.phpt deleted file mode 100644 index 8e3f7cc..0000000 --- a/ffmpeg-php/tests/isKeyFrame.phpt +++ /dev/null @@ -1,267 +0,0 @@ ---TEST-- -ffmpeg test key frame ---SKIPIF-- - ---FILE-- -getFrame()) != false) { - $i = $mov->getFrameNumber(); - $filename = $img . $i . '.png'; - $gd_image = $frame->toGDImage(); - imagepng($gd_image, $filename); - printf("ffmpeg frame->isKeyFrame($i)= %d\n", $frame->isKeyFrame()); - imagedestroy($gd_image); - unlink($filename); -} -?> ---EXPECT-- -ffmpeg frame->isKeyFrame(1)= 0 -ffmpeg frame->isKeyFrame(2)= 0 -ffmpeg frame->isKeyFrame(3)= 1 -ffmpeg frame->isKeyFrame(4)= 0 -ffmpeg frame->isKeyFrame(5)= 0 -ffmpeg frame->isKeyFrame(6)= 1 -ffmpeg frame->isKeyFrame(7)= 0 -ffmpeg frame->isKeyFrame(8)= 0 -ffmpeg frame->isKeyFrame(9)= 1 -ffmpeg frame->isKeyFrame(10)= 0 -ffmpeg frame->isKeyFrame(11)= 0 -ffmpeg frame->isKeyFrame(12)= 1 -ffmpeg frame->isKeyFrame(13)= 0 -ffmpeg frame->isKeyFrame(14)= 0 -ffmpeg frame->isKeyFrame(15)= 1 -ffmpeg frame->isKeyFrame(16)= 0 -ffmpeg frame->isKeyFrame(17)= 0 -ffmpeg frame->isKeyFrame(18)= 1 -ffmpeg frame->isKeyFrame(19)= 0 -ffmpeg frame->isKeyFrame(20)= 0 -ffmpeg frame->isKeyFrame(21)= 1 -ffmpeg frame->isKeyFrame(22)= 0 -ffmpeg frame->isKeyFrame(23)= 0 -ffmpeg frame->isKeyFrame(24)= 1 -ffmpeg frame->isKeyFrame(25)= 0 -ffmpeg frame->isKeyFrame(26)= 0 -ffmpeg frame->isKeyFrame(27)= 1 -ffmpeg frame->isKeyFrame(28)= 0 -ffmpeg frame->isKeyFrame(29)= 0 -ffmpeg frame->isKeyFrame(30)= 1 -ffmpeg frame->isKeyFrame(31)= 0 -ffmpeg frame->isKeyFrame(32)= 0 -ffmpeg frame->isKeyFrame(33)= 1 -ffmpeg frame->isKeyFrame(34)= 0 -ffmpeg frame->isKeyFrame(35)= 0 -ffmpeg frame->isKeyFrame(36)= 1 -ffmpeg frame->isKeyFrame(37)= 0 -ffmpeg frame->isKeyFrame(38)= 0 -ffmpeg frame->isKeyFrame(39)= 1 -ffmpeg frame->isKeyFrame(40)= 0 -ffmpeg frame->isKeyFrame(41)= 0 -ffmpeg frame->isKeyFrame(42)= 1 -ffmpeg frame->isKeyFrame(43)= 0 -ffmpeg frame->isKeyFrame(44)= 0 -ffmpeg frame->isKeyFrame(45)= 1 -ffmpeg frame->isKeyFrame(46)= 0 -ffmpeg frame->isKeyFrame(47)= 0 -ffmpeg frame->isKeyFrame(48)= 1 -ffmpeg frame->isKeyFrame(49)= 0 -ffmpeg frame->isKeyFrame(50)= 0 -ffmpeg frame->isKeyFrame(51)= 1 -ffmpeg frame->isKeyFrame(52)= 0 -ffmpeg frame->isKeyFrame(53)= 0 -ffmpeg frame->isKeyFrame(54)= 1 -ffmpeg frame->isKeyFrame(55)= 0 -ffmpeg frame->isKeyFrame(56)= 0 -ffmpeg frame->isKeyFrame(57)= 1 -ffmpeg frame->isKeyFrame(58)= 0 -ffmpeg frame->isKeyFrame(59)= 0 -ffmpeg frame->isKeyFrame(60)= 1 -ffmpeg frame->isKeyFrame(61)= 0 -ffmpeg frame->isKeyFrame(62)= 0 -ffmpeg frame->isKeyFrame(63)= 1 -ffmpeg frame->isKeyFrame(64)= 0 -ffmpeg frame->isKeyFrame(65)= 0 -ffmpeg frame->isKeyFrame(66)= 1 -ffmpeg frame->isKeyFrame(67)= 0 -ffmpeg frame->isKeyFrame(68)= 0 -ffmpeg frame->isKeyFrame(69)= 1 -ffmpeg frame->isKeyFrame(70)= 0 -ffmpeg frame->isKeyFrame(71)= 0 -ffmpeg frame->isKeyFrame(72)= 1 -ffmpeg frame->isKeyFrame(73)= 0 -ffmpeg frame->isKeyFrame(74)= 0 -ffmpeg frame->isKeyFrame(75)= 1 -ffmpeg frame->isKeyFrame(76)= 0 -ffmpeg frame->isKeyFrame(77)= 0 -ffmpeg frame->isKeyFrame(78)= 1 -ffmpeg frame->isKeyFrame(79)= 0 -ffmpeg frame->isKeyFrame(80)= 0 -ffmpeg frame->isKeyFrame(81)= 1 -ffmpeg frame->isKeyFrame(82)= 0 -ffmpeg frame->isKeyFrame(83)= 0 -ffmpeg frame->isKeyFrame(84)= 1 -ffmpeg frame->isKeyFrame(85)= 0 -ffmpeg frame->isKeyFrame(86)= 0 -ffmpeg frame->isKeyFrame(87)= 1 -ffmpeg frame->isKeyFrame(88)= 0 -ffmpeg frame->isKeyFrame(89)= 0 -ffmpeg frame->isKeyFrame(90)= 1 -ffmpeg frame->isKeyFrame(91)= 0 -ffmpeg frame->isKeyFrame(92)= 0 -ffmpeg frame->isKeyFrame(93)= 1 -ffmpeg frame->isKeyFrame(94)= 0 -ffmpeg frame->isKeyFrame(95)= 0 -ffmpeg frame->isKeyFrame(96)= 1 -ffmpeg frame->isKeyFrame(97)= 0 -ffmpeg frame->isKeyFrame(98)= 0 -ffmpeg frame->isKeyFrame(99)= 1 -ffmpeg frame->isKeyFrame(100)= 0 -ffmpeg frame->isKeyFrame(101)= 0 -ffmpeg frame->isKeyFrame(102)= 1 -ffmpeg frame->isKeyFrame(103)= 0 -ffmpeg frame->isKeyFrame(104)= 0 -ffmpeg frame->isKeyFrame(105)= 1 -ffmpeg frame->isKeyFrame(106)= 0 -ffmpeg frame->isKeyFrame(107)= 0 -ffmpeg frame->isKeyFrame(108)= 1 -ffmpeg frame->isKeyFrame(109)= 0 -ffmpeg frame->isKeyFrame(110)= 0 -ffmpeg frame->isKeyFrame(111)= 1 -ffmpeg frame->isKeyFrame(112)= 0 -ffmpeg frame->isKeyFrame(113)= 0 -ffmpeg frame->isKeyFrame(114)= 1 -ffmpeg frame->isKeyFrame(115)= 0 -ffmpeg frame->isKeyFrame(116)= 0 -ffmpeg frame->isKeyFrame(117)= 1 -ffmpeg frame->isKeyFrame(118)= 0 -ffmpeg frame->isKeyFrame(119)= 0 -ffmpeg frame->isKeyFrame(120)= 1 -ffmpeg frame->isKeyFrame(121)= 0 -ffmpeg frame->isKeyFrame(122)= 0 -ffmpeg frame->isKeyFrame(123)= 1 -ffmpeg frame->isKeyFrame(124)= 0 -ffmpeg frame->isKeyFrame(125)= 0 -ffmpeg frame->isKeyFrame(126)= 1 -ffmpeg frame->isKeyFrame(127)= 0 -ffmpeg frame->isKeyFrame(128)= 0 -ffmpeg frame->isKeyFrame(129)= 1 -ffmpeg frame->isKeyFrame(130)= 0 -ffmpeg frame->isKeyFrame(131)= 0 -ffmpeg frame->isKeyFrame(132)= 1 -ffmpeg frame->isKeyFrame(133)= 0 -ffmpeg frame->isKeyFrame(134)= 0 -ffmpeg frame->isKeyFrame(135)= 1 -ffmpeg frame->isKeyFrame(136)= 0 -ffmpeg frame->isKeyFrame(137)= 0 -ffmpeg frame->isKeyFrame(138)= 1 -ffmpeg frame->isKeyFrame(139)= 0 -ffmpeg frame->isKeyFrame(140)= 0 -ffmpeg frame->isKeyFrame(141)= 1 -ffmpeg frame->isKeyFrame(142)= 0 -ffmpeg frame->isKeyFrame(143)= 0 -ffmpeg frame->isKeyFrame(144)= 1 -ffmpeg frame->isKeyFrame(145)= 0 -ffmpeg frame->isKeyFrame(146)= 0 -ffmpeg frame->isKeyFrame(147)= 1 -ffmpeg frame->isKeyFrame(148)= 0 -ffmpeg frame->isKeyFrame(149)= 0 -ffmpeg frame->isKeyFrame(150)= 1 -ffmpeg frame->isKeyFrame(151)= 0 -ffmpeg frame->isKeyFrame(152)= 0 -ffmpeg frame->isKeyFrame(153)= 1 -ffmpeg frame->isKeyFrame(154)= 0 -ffmpeg frame->isKeyFrame(155)= 0 -ffmpeg frame->isKeyFrame(156)= 1 -ffmpeg frame->isKeyFrame(157)= 0 -ffmpeg frame->isKeyFrame(158)= 0 -ffmpeg frame->isKeyFrame(159)= 1 -ffmpeg frame->isKeyFrame(160)= 0 -ffmpeg frame->isKeyFrame(161)= 0 -ffmpeg frame->isKeyFrame(162)= 1 -ffmpeg frame->isKeyFrame(163)= 0 -ffmpeg frame->isKeyFrame(164)= 0 -ffmpeg frame->isKeyFrame(165)= 1 -ffmpeg frame->isKeyFrame(166)= 0 -ffmpeg frame->isKeyFrame(167)= 0 -ffmpeg frame->isKeyFrame(168)= 1 -ffmpeg frame->isKeyFrame(169)= 0 -ffmpeg frame->isKeyFrame(170)= 0 -ffmpeg frame->isKeyFrame(171)= 1 -ffmpeg frame->isKeyFrame(172)= 0 -ffmpeg frame->isKeyFrame(173)= 0 -ffmpeg frame->isKeyFrame(174)= 1 -ffmpeg frame->isKeyFrame(175)= 0 -ffmpeg frame->isKeyFrame(176)= 0 -ffmpeg frame->isKeyFrame(177)= 1 -ffmpeg frame->isKeyFrame(178)= 0 -ffmpeg frame->isKeyFrame(179)= 0 -ffmpeg frame->isKeyFrame(180)= 1 -ffmpeg frame->isKeyFrame(181)= 0 -ffmpeg frame->isKeyFrame(182)= 0 -ffmpeg frame->isKeyFrame(183)= 1 -ffmpeg frame->isKeyFrame(184)= 0 -ffmpeg frame->isKeyFrame(185)= 0 -ffmpeg frame->isKeyFrame(186)= 1 -ffmpeg frame->isKeyFrame(187)= 0 -ffmpeg frame->isKeyFrame(188)= 0 -ffmpeg frame->isKeyFrame(189)= 1 -ffmpeg frame->isKeyFrame(190)= 0 -ffmpeg frame->isKeyFrame(191)= 0 -ffmpeg frame->isKeyFrame(192)= 1 -ffmpeg frame->isKeyFrame(193)= 0 -ffmpeg frame->isKeyFrame(194)= 0 -ffmpeg frame->isKeyFrame(195)= 1 -ffmpeg frame->isKeyFrame(196)= 0 -ffmpeg frame->isKeyFrame(197)= 0 -ffmpeg frame->isKeyFrame(198)= 1 -ffmpeg frame->isKeyFrame(199)= 0 -ffmpeg frame->isKeyFrame(200)= 0 -ffmpeg frame->isKeyFrame(201)= 1 -ffmpeg frame->isKeyFrame(202)= 0 -ffmpeg frame->isKeyFrame(203)= 0 -ffmpeg frame->isKeyFrame(204)= 1 -ffmpeg frame->isKeyFrame(205)= 0 -ffmpeg frame->isKeyFrame(206)= 0 -ffmpeg frame->isKeyFrame(207)= 1 -ffmpeg frame->isKeyFrame(208)= 0 -ffmpeg frame->isKeyFrame(209)= 0 -ffmpeg frame->isKeyFrame(210)= 1 -ffmpeg frame->isKeyFrame(211)= 0 -ffmpeg frame->isKeyFrame(212)= 0 -ffmpeg frame->isKeyFrame(213)= 1 -ffmpeg frame->isKeyFrame(214)= 0 -ffmpeg frame->isKeyFrame(215)= 0 -ffmpeg frame->isKeyFrame(216)= 1 -ffmpeg frame->isKeyFrame(217)= 0 -ffmpeg frame->isKeyFrame(218)= 0 -ffmpeg frame->isKeyFrame(219)= 1 -ffmpeg frame->isKeyFrame(220)= 0 -ffmpeg frame->isKeyFrame(221)= 0 -ffmpeg frame->isKeyFrame(222)= 1 -ffmpeg frame->isKeyFrame(223)= 0 -ffmpeg frame->isKeyFrame(224)= 0 -ffmpeg frame->isKeyFrame(225)= 1 -ffmpeg frame->isKeyFrame(226)= 0 -ffmpeg frame->isKeyFrame(227)= 0 -ffmpeg frame->isKeyFrame(228)= 1 -ffmpeg frame->isKeyFrame(229)= 0 -ffmpeg frame->isKeyFrame(230)= 0 -ffmpeg frame->isKeyFrame(231)= 1 -ffmpeg frame->isKeyFrame(232)= 0 -ffmpeg frame->isKeyFrame(233)= 0 -ffmpeg frame->isKeyFrame(234)= 1 -ffmpeg frame->isKeyFrame(235)= 0 -ffmpeg frame->isKeyFrame(236)= 0 -ffmpeg frame->isKeyFrame(237)= 1 -ffmpeg frame->isKeyFrame(238)= 0 -ffmpeg frame->isKeyFrame(239)= 0 -ffmpeg frame->isKeyFrame(240)= 1 -ffmpeg frame->isKeyFrame(241)= 0 -ffmpeg frame->isKeyFrame(242)= 0 diff --git a/ffmpeg-php/tests/persistentMovie.phpt b/ffmpeg-php/tests/persistentMovie.phpt deleted file mode 100644 index 59c9aea..0000000 --- a/ffmpeg-php/tests/persistentMovie.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -ffmpeg persistent movie test ---SKIPIF-- - ---FILE-- -getDuration()); -printf("ffmpeg getDuration(): %0.2f\n", $mov2->getDuration()); -?> ---EXPECT-- -ffmpeg getDuration(): 9.60 -ffmpeg getDuration(): 9.60 diff --git a/ffmpeg-php/tests/test_media/16Hz-20kHz-Exp-1f-5sec.mp3 b/ffmpeg-php/tests/test_media/16Hz-20kHz-Exp-1f-5sec.mp3 deleted file mode 100644 index 89dcdd8f093783c3204844f7ae4672fbc322a32e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43008 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 BS1Q?Rh>C~w@e3_o6nR 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

k0rP$hAr;At5j9e(QAkDA@u)CPO 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 AYuGCTb;sVZ2B5 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�Nvj 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%0A`6 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