commit 89f766d0817833337063840b5f30b85715689ac1 parent 19978b3a5b0bea9b139601f40c2e61dcd7cbfafc Author: Heikki Lindholm <holin@iki.fi> Date: Sun, 20 Jul 2008 09:49:17 +0000 sync ffmpeg (ffmpeg r14311, swscaler r27330) Diffstat:
215 files changed, 6921 insertions(+), 4883 deletions(-)
diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/Changelog b/src/plugins/thumbnailffmpeg/ffmpeg/Changelog @@ -122,6 +122,11 @@ version <next> - MAXIS EA XA (.xa) demuxer / decoder - BFI video decoder - OMA demuxer +- MLP/TrueHD decoder +- Electronic Arts CMV decoder +- Motion Pixels Video decoder +- Motion Pixels MVI demuxer +- removed animated GIF decoder/demuxer version 0.4.9-pre1: diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/Makefile b/src/plugins/thumbnailffmpeg/ffmpeg/Makefile @@ -262,6 +262,15 @@ LAVF_REG = tests/data/lavf.regression ROTOZOOM_REG = tests/data/rotozoom.regression VSYNTH_REG = tests/data/vsynth.regression +ifeq ($(CONFIG_SWSCALE),yes) +servertest codectest $(CODEC_TESTS) libavtest: swscale_error +swscale_error: + @echo + @echo "This regression test is incompatible with --enable-swscale." + @echo + @exit 1 +endif + codectest: $(VSYNTH_REG) $(ROTOZOOM_REG) diff -u -w $(FFMPEG_REFFILE) $(VSYNTH_REG) diff -u -w $(ROTOZOOM_REFFILE) $(ROTOZOOM_REG) @@ -301,15 +310,6 @@ servertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/asynth1.sw @echo $(SRC_PATH)/tests/server-regression.sh $(FFSERVER_REFFILE) $(SRC_PATH)/tests/test.conf -ifeq ($(CONFIG_SWSCALE),yes) -servertest codectest $(CODEC_TESTS) libavtest: swscale_error -swscale_error: - @echo - @echo "This regression test is incompatible with --enable-swscale." - @echo - @exit 1 -endif - tests/vsynth1/00.pgm: tests/videogen$(EXESUF) mkdir -p tests/vsynth1 $(BUILD_ROOT)/$< 'tests/vsynth1/' diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/cmdutils.c b/src/plugins/thumbnailffmpeg/ffmpeg/cmdutils.c @@ -230,40 +230,43 @@ void show_license(void) { #ifdef CONFIG_NONFREE printf( - "This version of FFmpeg has nonfree parts compiled in.\n" - "Therefore it is not legally redistributable.\n" + "This version of %s has nonfree parts compiled in.\n" + "Therefore it is not legally redistributable.\n", + program_name ); #elif CONFIG_GPL printf( - "FFmpeg is free software; you can redistribute it and/or modify\n" + "%s is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n" "\n" - "FFmpeg is distributed in the hope that it will be useful,\n" + "%s is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" - "along with FFmpeg; if not, write to the Free Software\n" - "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" + "along with %s; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n", + program_name, program_name, program_name ); #else printf( - "FFmpeg is free software; you can redistribute it and/or\n" + "%s is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU Lesser General Public\n" "License as published by the Free Software Foundation; either\n" "version 2.1 of the License, or (at your option) any later version.\n" "\n" - "FFmpeg is distributed in the hope that it will be useful,\n" + "%s is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" "Lesser General Public License for more details.\n" "\n" "You should have received a copy of the GNU Lesser General Public\n" - "License along with FFmpeg; if not, write to the Free Software\n" - "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" + "License along with %s; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n", + program_name, program_name, program_name ); #endif } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/common.mak b/src/plugins/thumbnailffmpeg/ffmpeg/common.mak @@ -38,6 +38,8 @@ CFLAGS := -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ %.d: %.cpp $(DEPEND_CMD) > $@ +%.o: %.d + %$(EXESUF): %.c SVN_ENTRIES = $(SRC_PATH_BARE)/.svn/entries diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/configure b/src/plugins/thumbnailffmpeg/ffmpeg/configure @@ -269,11 +269,13 @@ disable(){ } enabled(){ - eval test "x\$$1" = "xyes" + test "${1#!}" = "$1" && op== || op=!= + eval test "x\$${1#!}" $op "xyes" } disabled(){ - eval test "x\$$1" = "xno" + test "${1#!}" = "$1" && op== || op=!= + eval test "x\$${1#!}" $op "xno" } enabled_all(){ @@ -317,6 +319,7 @@ is_in(){ check_deps(){ for cfg; do + cfg="${cfg#!}" enabled ${cfg}_checking && die "Circular dependency for $cfg." disabled ${cfg}_checking && continue enable ${cfg}_checking @@ -827,11 +830,15 @@ neon_deps="armv4l" ssse3_deps="x86" vis_deps="sparc" +# system headers and functions +byteswap_h_deps="!armv4l" + # decoders / encoders -ac3_decoder_deps="gpl" +ac3_decoder_deps="gpl !liba52" dxa_decoder_deps="zlib" flashsv_decoder_deps="zlib" flashsv_encoder_deps="zlib" +mlp_decoder_deps="mlp_parser" mpeg_xvmc_decoder_deps="xvmc" png_decoder_deps="zlib" png_encoder_deps="zlib" @@ -845,7 +852,7 @@ libamr_nb_decoder_deps="libamr_nb" libamr_nb_encoder_deps="libamr_nb" libamr_wb_decoder_deps="libamr_wb" libamr_wb_encoder_deps="libamr_wb" -libdirac_decoder_deps="libdirac" +libdirac_decoder_deps="libdirac !libschroedinger" libdirac_encoder_deps="libdirac" libfaac_encoder_deps="libfaac" libfaad_decoder_deps="libfaad" @@ -955,7 +962,6 @@ vhook="default" # build settings SHFLAGS='-shared -Wl,-soname,$$(@F)' VHOOKSHFLAGS='$(SHFLAGS)' -LDLATEFLAGS='-Wl,-rpath-link,\$(BUILD_ROOT)/libpostproc -Wl,-rpath-link,\$(BUILD_ROOT)/libswscale -Wl,-rpath-link,\$(BUILD_ROOT)/libavfilter -Wl,-rpath-link,\$(BUILD_ROOT)/libavdevice -Wl,-rpath-link,\$(BUILD_ROOT)/libavformat -Wl,-rpath-link,\$(BUILD_ROOT)/libavcodec -Wl,-rpath-link,\$(BUILD_ROOT)/libavutil' FFSERVERLDFLAGS=-Wl,-E LIBPREF="lib" LIBSUF=".a" @@ -1286,7 +1292,6 @@ case $target_os in EXESUF=".exe" ;; linux) - LDLATEFLAGS="-Wl,--as-needed $LDLATEFLAGS" enable dv1394 ;; irix*) @@ -1399,7 +1404,7 @@ if test $target_os = darwin; then fi fi -disabled optimizations || add_cflags -fomit-frame-pointer +disabled optimizations || check_cflags -fomit-frame-pointer # Add processor-specific flags if test $cpu != "generic"; then @@ -1684,12 +1689,6 @@ enabled libx264 && require x264 x264.h x264_encoder_open -lx264 -lm enabled libxvid && require Xvid xvid.h xvid_global -lxvidcore enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib -# disable the native AC-3 decoder if liba52 is enabled -enabled liba52 && disable ac3_decoder - -# disable the slower libdirac decoder if libschroedinger is enabled -enabled libschroedinger && enabled libdirac && disable libdirac_decoder - # libdc1394 check if enabled libdc1394; then { check_lib dc1394/dc1394.h dc1394_new -ldc1394 -lraw1394 && @@ -1830,7 +1829,8 @@ enabled extra_warnings && check_cflags -Winline # add some linker flags check_ldflags -Wl,--warn-common -check_ldflags $LDLATEFLAGS +check_ldflags -Wl,--as-needed +check_ldflags '-Wl,-rpath-link,\$(BUILD_ROOT)/libpostproc -Wl,-rpath-link,\$(BUILD_ROOT)/libswscale -Wl,-rpath-link,\$(BUILD_ROOT)/libavfilter -Wl,-rpath-link,\$(BUILD_ROOT)/libavdevice -Wl,-rpath-link,\$(BUILD_ROOT)/libavformat -Wl,-rpath-link,\$(BUILD_ROOT)/libavcodec -Wl,-rpath-link,\$(BUILD_ROOT)/libavutil' check_ldflags -Wl,-Bsymbolic if enabled small; then @@ -1868,7 +1868,7 @@ if enabled shared; then # LIBOBJFLAGS may have already been set in the OS configuration if test -z "$LIBOBJFLAGS" ; then case "$arch" in - x86_64|ia64|alpha|sparc*|power*) LIBOBJFLAGS='$(PIC)' ;; + x86_64|ia64|alpha|sparc*|power*|parisc*) LIBOBJFLAGS='$(PIC)' ;; esac fi fi @@ -2019,6 +2019,7 @@ echo "#ifndef FFMPEG_CONFIG_H" >> $TMPH echo "#define FFMPEG_CONFIG_H" >> $TMPH echo "#define FFMPEG_CONFIGURATION \"$FFMPEG_CONFIGURATION\"" >> $TMPH +echo "FFMPEG_CONFIGURATION=$FFMPEG_CONFIGURATION" >> config.mak echo "prefix=$prefix" >> config.mak echo "LIBDIR=\$(DESTDIR)$libdir" >> config.mak echo "SHLIBDIR=\$(DESTDIR)$shlibdir" >> config.mak @@ -2211,8 +2212,8 @@ EOF cat <<EOF > $name/$name-uninstalled.pc prefix= exec_prefix= -libdir=\${pcfiledir}/$name -includedir=\${pcfiledir} +libdir=\${pcfiledir} +includedir=\${pcfiledir}/.. Name: $name Description: $comment diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/doc/ffserver-doc.texi b/src/plugins/thumbnailffmpeg/ffmpeg/doc/ffserver-doc.texi @@ -16,15 +16,15 @@ several live feeds, streaming from files and time shifting on live feeds (you can seek to positions in the past on each live feed, provided you specify a big enough feed storage in ffserver.conf). +FFserver runs in daemon mode by default; that is, it puts itself in +the background and detaches from its TTY, unless it is launched in +debug mode or a NoDaemon option is specified in the configuration +file. + This documentation covers only the streaming aspects of ffserver / ffmpeg. All questions about parameters for ffmpeg, codec questions, etc. are not covered here. Read @file{ffmpeg-doc.html} for more information. -@c man end - -@chapter Quick Start - -[Contributed by Philip Gladstone, philip-ffserver at gladstonefamily dot net] @section How does it work? @@ -224,6 +224,7 @@ may be in the future and so is unlikely to be useful. You use this by adding the ?date= to the end of the URL for the stream. For example: @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}. +@c man end @chapter Invocation @section Syntax @@ -246,6 +247,14 @@ Show available formats, codecs, protocols, ... Show help. @item -f @var{configfile} Use @file{configfile} instead of @file{/etc/ffserver.conf}. +@item -n +Enable no-launch mode. This option disables all the Launch directives +within the various <Stream> sections. FFserver will not launch any +ffmpeg instance, so you will have to launch them manually. +@item -d +Enable debug mode. This option increases log verbosity, directs log +messages to stdout and causes ffserver to run in the foreground +rather than as a daemon. @end table @c man end diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/doc/general.texi b/src/plugins/thumbnailffmpeg/ffmpeg/doc/general.texi @@ -41,106 +41,109 @@ library: @multitable @columnfractions .4 .1 .1 .4 @item Supported File Format @tab Encoding @tab Decoding @tab Comments -@item MPEG audio @tab X @tab X -@item MPEG-1 systems @tab X @tab X -@tab muxed audio and video -@item MPEG-2 PS @tab X @tab X -@tab also known as @code{VOB} file -@item MPEG-2 TS @tab @tab X -@tab also known as DVB Transport Stream -@item ASF@tab X @tab X -@item AVI@tab X @tab X -@item WAV@tab X @tab X -@item Macromedia Flash@tab X @tab X -@item AVM2 (Flash 9) @tab X @tab X -@tab Only embedded audio is decoded. -@item FLV @tab X @tab X -@tab Macromedia Flash video files -@item Real Audio and Video @tab X @tab X -@item Raw AC3 @tab X @tab X -@item Raw MJPEG @tab X @tab X -@item Raw MPEG video @tab X @tab X -@item Raw PCM8/16 bits, mulaw/Alaw@tab X @tab X -@item Raw CRI ADX audio @tab X @tab X -@item Raw Shorten audio @tab @tab X -@item SUN AU format @tab X @tab X -@item NUT @tab X @tab X @tab NUT Open Container Format -@item QuickTime @tab X @tab X -@item MPEG-4 @tab X @tab X -@tab MPEG-4 is a variant of QuickTime. -@item Raw MPEG4 video @tab X @tab X -@item DV @tab X @tab X -@item 4xm @tab @tab X -@tab 4X Technologies format, used in some games. -@item PlayStation STR @tab @tab X -@item id RoQ @tab X @tab X -@tab Used in Quake III, Jedi Knight 2, other computer games. -@item Interplay MVE @tab @tab X -@tab Format used in various Interplay computer games. -@item WC3 Movie @tab @tab X -@tab Multimedia format used in Origin's Wing Commander III computer game. -@item Sega FILM/CPK @tab @tab X -@tab Used in many Sega Saturn console games. -@item Westwood Studios VQA/AUD @tab @tab X -@tab Multimedia formats used in Westwood Studios games. -@item id Cinematic (.cin) @tab @tab X -@tab Used in Quake II. -@item FLIC format @tab @tab X -@tab .fli/.flc files -@item Sierra VMD @tab @tab X -@tab Used in Sierra CD-ROM games. -@item Sierra Online @tab @tab X -@tab .sol files used in Sierra Online games. -@item Matroska @tab X @tab X -@item Electronic Arts Multimedia @tab @tab X -@tab Used in various EA games; files have extensions like WVE and UV2. -@item MAXIS EA XA @tab @tab X -@tab Used in Sim City 3000; file extension .xa. -@item Nullsoft Video (NSV) format @tab @tab X -@item ADTS AAC audio @tab X @tab X -@item Creative VOC @tab X @tab X @tab Created for the Sound Blaster Pro. -@item American Laser Games MM @tab @tab X -@tab Multimedia format used in games like Mad Dog McCree -@item AVS @tab @tab X -@tab Multimedia format used by the Creature Shock game. -@item Smacker @tab @tab X -@tab Multimedia format used by many games. -@item GXF @tab X @tab X -@tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley playout servers. -@item CIN @tab @tab X -@tab Multimedia format used by Delphine Software games. -@item MXF @tab @tab X -@tab Material eXchange Format SMPTE 377M, used by D-Cinema, broadcast industry. -@item SEQ @tab @tab X -@tab Tiertex .seq files used in the DOS CD-ROM version of the game Flashback. -@item DXA @tab @tab X -@tab This format is used in non-Windows version of Feeble Files game and -different game cutscenes repacked for use with ScummVM. -@item THP @tab @tab X -@tab Used on the Nintendo GameCube. -@item C93 @tab @tab X -@tab Used in the game Cyberia from Interplay. -@item Bethsoft VID @tab @tab X -@tab Used in some games from Bethesda Softworks. -@item CRYO APC @tab @tab X -@tab Audio format used in some games by CRYO Interactive Entertainment. -@item Monkey's Audio @tab @tab X -@item SIFF @tab @tab X -@tab Audio and video format used in some games by Beam Software -@item LMLM4 @tab @tab X -@tab Used by Linux Media Labs MPEG-4 PCI boards -@item PVA @tab @tab X -@tab Used by TechnoTrend DVB PCI boards -@item MSN TCP Webcam @tab @tab X -@tab Used by MSN Messenger Webcam streams. -@item RL2 @tab @tab X -@tab Audio and video format used in some games by Entertainment Software Partners -@item IFF @tab @tab X -@tab Interchange File Format -@item BFI @tab @tab X -@tab Brute Force & Ignorance, used in Flash Traffic: City of Angels -@item OMA @tab @tab X -@tab Audio format used in Sony Sonic Stage and Sony Vegas +@item 4xm @tab @tab X + @tab 4X Technologies format, used in some games. +@item ADTS AAC audio @tab X @tab X +@item American Laser Games MM @tab @tab X + @tab Multimedia format used in games like Mad Dog McCree. +@item ASF @tab X @tab X +@item AVI @tab X @tab X +@item AVM2 (Flash 9) @tab X @tab X + @tab Only embedded audio is decoded. +@item AVS @tab @tab X + @tab Multimedia format used by the Creature Shock game. +@item Bethsoft VID @tab @tab X + @tab Used in some games from Bethesda Softworks. +@item BFI @tab @tab X + @tab Brute Force & Ignorance, used in Flash Traffic: City of Angels. +@item C93 @tab @tab X + @tab Used in the game Cyberia from Interplay. +@item CIN @tab @tab X + @tab Multimedia format used by Delphine Software games. +@item Creative VOC @tab X @tab X + @tab Created for the Sound Blaster Pro. +@item CRYO APC @tab @tab X + @tab Audio format used in some games by CRYO Interactive Entertainment. +@item DV @tab X @tab X +@item DXA @tab @tab X + @tab This format is used in the non-Windows version of the Feeble Files + game and different game cutscenes repacked for use with ScummVM. +@item Electronic Arts Multimedia @tab @tab X + @tab Used in various EA games; files have extensions like WVE and UV2. +@item FLIC @tab @tab X + @tab .fli/.flc files +@item FLV @tab X @tab X + @tab Macromedia Flash video files +@item GXF @tab X @tab X + @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley + playout servers. +@item id Cinematic @tab @tab X + @tab Used in Quake II. +@item id RoQ @tab X @tab X + @tab Used in Quake III, Jedi Knight 2, other computer games. +@item IFF @tab @tab X + @tab Interchange File Format +@item Interplay MVE @tab @tab X + @tab Format used in various Interplay computer games. +@item LMLM4 @tab @tab X + @tab Used by Linux Media Labs MPEG-4 PCI boards +@item Matroska @tab X @tab X +@item MAXIS EA XA @tab @tab X + @tab Used in Sim City 3000; file extension .xa. +@item Monkey's Audio @tab @tab X +@item Motion Pixels MVI @tab @tab X +@item MOV/QuickTime @tab X @tab X +@item MPEG audio @tab X @tab X +@item MPEG-1 systems @tab X @tab X + @tab muxed audio and video +@item MPEG-2 PS @tab X @tab X + @tab also known as @code{VOB} file +@item MPEG-2 TS @tab @tab X + @tab also known as DVB Transport Stream +@item MPEG-4 @tab X @tab X + @tab MPEG-4 is a variant of QuickTime. +@item MSN TCP webcam @tab @tab X + @tab Used by MSN Messenger webcam streams. +@item MXF @tab @tab X + @tab Material eXchange Format SMPTE 377M, used by D-Cinema, broadcast industry. +@item Nullsoft Video @tab @tab X +@item NUT @tab X @tab X + @tab NUT Open Container Format +@item OMA @tab @tab X + @tab Audio format used in Sony Sonic Stage and Sony Vegas. +@item PlayStation STR @tab @tab X +@item PVA @tab @tab X + @tab Used by TechnoTrend DVB PCI boards. +@item raw AC-3 @tab X @tab X +@item raw CRI ADX audio @tab X @tab X +@item raw MJPEG @tab X @tab X +@item raw MPEG video @tab X @tab X +@item raw MPEG-4 video @tab X @tab X +@item raw PCM 8/16 bits, mu-law/A-law @tab X @tab X +@item raw Shorten audio @tab @tab X +@item RealMedia @tab X @tab X +@item RL2 @tab @tab X + @tab Audio and video format used in some games by Entertainment Software Partners. +@item Sega FILM/CPK @tab @tab X + @tab Used in many Sega Saturn console games. +@item SEQ @tab @tab X + @tab Tiertex .seq files used in the DOS CD-ROM version of the game Flashback. +@item Sierra Online @tab @tab X + @tab .sol files used in Sierra Online games. +@item Sierra VMD @tab @tab X + @tab Used in Sierra CD-ROM games. +@item SIFF @tab @tab X + @tab Audio and video format used in some games by Beam Software. +@item Smacker @tab @tab X + @tab Multimedia format used by many games. +@item SUN AU format @tab X @tab X +@item THP @tab @tab X + @tab Used on the Nintendo GameCube. +@item WAV @tab X @tab X +@item WC3 Movie @tab @tab X + @tab Multimedia format used in Origin's Wing Commander III computer game. +@item Westwood Studios VQA/AUD @tab @tab X + @tab Multimedia formats used in Westwood Studios games. @end multitable @code{X} means that encoding (resp. decoding) is supported. @@ -152,19 +155,19 @@ following image formats are supported: @multitable @columnfractions .4 .1 .1 .4 @item Supported Image Format @tab Encoding @tab Decoding @tab Comments -@item PGM, PPM @tab X @tab X -@item PAM @tab X @tab X @tab PAM is a PNM extension with alpha support. -@item PGMYUV @tab X @tab X @tab PGM with U and V components in YUV 4:2:0 -@item JPEG @tab X @tab X @tab Progressive JPEG is not supported. @item .Y.U.V @tab X @tab X @tab one raw file per component @item animated GIF @tab X @tab X @tab Only uncompressed GIFs are generated. -@item PNG @tab X @tab X @tab 2 bit and 4 bit/pixel not supported yet. -@item Targa @tab @tab X @tab Targa (.TGA) image format. -@item TIFF @tab X @tab X @tab YUV, JPEG and some extension is not supported yet. -@item SGI @tab X @tab X @tab SGI RGB image format +@item JPEG @tab X @tab X @tab Progressive JPEG is not supported. +@item PAM @tab X @tab X @tab PAM is a PNM extension with alpha support. +@item PCX @tab @tab X @tab PC Paintbrush +@item PGM, PPM @tab X @tab X +@item PGMYUV @tab X @tab X @tab PGM with U and V components in YUV 4:2:0 +@item PNG @tab X @tab X @tab 2/4 bpp not supported yet @item PTX @tab @tab X @tab V.Flash PTX format @item RAS @tab @tab X @tab Sun Rasterfile -@item PCX @tab @tab X @tab PC Paintbrush +@item SGI @tab X @tab X @tab SGI RGB image format +@item Targa @tab @tab X @tab Targa (.TGA) image format +@item TIFF @tab X @tab X @tab YUV, JPEG and some extension is not supported yet. @end multitable @code{X} means that encoding (resp. decoding) is supported. @@ -173,92 +176,155 @@ following image formats are supported: @multitable @columnfractions .4 .1 .1 .4 @item Supported Codec @tab Encoding @tab Decoding @tab Comments -@item MPEG-1 video @tab X @tab X -@item MPEG-2 video @tab X @tab X +@item 4X Video @tab @tab X + @tab Used in certain computer games. +@item American Laser Games Video @tab @tab X + @tab Used in games like Mad Dog McCree. +@item AMV @tab @tab X + @tab Used in Chinese MP3 players. +@item Apple Animation @tab X @tab X + @tab fourcc: 'rle ' +@item Apple Graphics @tab @tab X + @tab fourcc: 'smc ' +@item Apple MJPEG-B @tab @tab X +@item Apple QuickDraw @tab @tab X + @tab fourcc: qdrw +@item Apple Video @tab @tab X + @tab fourcc: rpza +@item Asus v1 @tab X @tab X + @tab fourcc: ASV1 +@item Asus v2 @tab X @tab X + @tab fourcc: ASV2 +@item ATI VCR1 @tab @tab X + @tab fourcc: VCR1 +@item ATI VCR2 @tab @tab X + @tab fourcc: VCR2 +@item Autodesk RLE @tab @tab X + @tab fourcc: AASC +@item AVID DNxHD @tab X @tab X + @tab aka SMPTE VC3 +@item AVS video @tab @tab X + @tab Video encoding used by the Creature Shock game. +@item Bethsoft VID @tab @tab X + @tab Used in some games from Bethesda Softworks. +@item C93 video @tab @tab X + @tab Codec used in Cyberia game. +@item CamStudio @tab @tab X + @tab fourcc: CSCD +@item Cin video @tab @tab X + @tab Codec used in Delphine Software games. +@item Cinepak @tab @tab X +@item Cirrus Logic AccuPak @tab @tab X + @tab fourcc: CLJR +@item Creative YUV @tab @tab X + @tab fourcc: CYUV +@item Dirac @tab X @tab X + @tab Supported through the external libdirac/libschroedinger libraries. +@item Duck TrueMotion v1 @tab @tab X + @tab fourcc: DUCK +@item Duck TrueMotion v2 @tab @tab X + @tab fourcc: TM20 +@item DV @tab X @tab X +@item DXA Video @tab @tab X + @tab Codec originally used in Feeble Files game. +@item Electronic Arts CMV @tab @tab X + @tab Used in NHL 95 game. +@item FFmpeg Video 1 @tab X @tab X + @tab experimental lossless codec (fourcc: FFV1) +@item Flash Screen Video @tab X @tab X + @tab fourcc: FSV1 +@item FLIC video @tab @tab X +@item FLV @tab X @tab X + @tab Sorenson H.263 used in Flash +@item Fraps FPS1 @tab @tab X +@item H.261 @tab X @tab X +@item H.263(+) @tab X @tab X + @tab also known as RealVideo 1.0 +@item H.264 @tab @tab X +@item HuffYUV @tab X @tab X +@item IBM Ultimotion @tab @tab X + @tab fourcc: ULTI +@item id Cinematic video @tab @tab X + @tab Used in Quake II. +@item id RoQ @tab X @tab X + @tab Used in Quake III, Jedi Knight 2, other computer games. +@item Intel Indeo 3 @tab @tab X +@item Interplay Video @tab @tab X + @tab Used in Interplay .MVE files. +@item JPEG-LS @tab X @tab X + @tab fourcc: MJLS, lossless and near-lossless is supported. +@item KMVC @tab @tab X + @tab Codec used in Worms games. +@item LOCO @tab @tab X +@item lossless MJPEG @tab X @tab X +@item Microsoft RLE @tab @tab X +@item Microsoft Video-1 @tab @tab X +@item Mimic @tab @tab X + @tab Used in MSN Messenger Webcam streams. +@item Miro VideoXL @tab @tab X + @tab fourcc: VIXL +@item MJPEG @tab X @tab X +@item Motion Pixels Video @tab @tab X +@item MPEG-1 @tab X @tab X +@item MPEG-2 @tab X @tab X @item MPEG-4 @tab X @tab X @item MSMPEG4 V1 @tab X @tab X @item MSMPEG4 V2 @tab X @tab X @item MSMPEG4 V3 @tab X @tab X -@item WMV7 @tab X @tab X -@item WMV8 @tab X @tab X @tab not completely working -@item WMV9 @tab @tab X @tab not completely working -@item VC1 @tab @tab X -@item H.261 @tab X @tab X -@item H.263(+) @tab X @tab X @tab also known as RealVideo 1.0 -@item H.264 @tab @tab X +@item MSZH @tab @tab X + @tab Part of LCL +@item On2 VP3 @tab @tab X + @tab still experimental +@item On2 VP5 @tab @tab X + @tab fourcc: VP50 +@item On2 VP6 @tab @tab X + @tab fourcc: VP60,VP61,VP62 +@item planar RGB @tab @tab X + @tab fourcc: 8BPS +@item QPEG @tab @tab X + @tab fourccs: QPEG, Q1.0, Q1.1 @item RealVideo 1.0 @tab X @tab X @item RealVideo 2.0 @tab X @tab X -@item MJPEG @tab X @tab X -@item lossless MJPEG @tab X @tab X -@item JPEG-LS @tab X @tab X @tab fourcc: MJLS, lossless and near-lossless is supported -@item Apple MJPEG-B @tab @tab X -@item Sunplus MJPEG @tab @tab X @tab fourcc: SP5X -@item DV @tab X @tab X -@item HuffYUV @tab X @tab X -@item FFmpeg Video 1 @tab X @tab X @tab experimental lossless codec (fourcc: FFV1) -@item FFmpeg Snow @tab X @tab X @tab experimental wavelet codec (fourcc: SNOW) -@item Asus v1 @tab X @tab X @tab fourcc: ASV1 -@item Asus v2 @tab X @tab X @tab fourcc: ASV2 -@item Creative YUV @tab @tab X @tab fourcc: CYUV -@item Sorenson Video 1 @tab X @tab X @tab fourcc: SVQ1 -@item Sorenson Video 3 @tab @tab X @tab fourcc: SVQ3 -@item On2 VP3 @tab @tab X @tab still experimental -@item On2 VP5 @tab @tab X @tab fourcc: VP50 -@item On2 VP6 @tab @tab X @tab fourcc: VP60,VP61,VP62 -@item Theora @tab X @tab X @tab still experimental -@item Intel Indeo 3 @tab @tab X -@item FLV @tab X @tab X @tab Sorenson H.263 used in Flash -@item Flash Screen Video @tab X @tab X @tab fourcc: FSV1 -@item ATI VCR1 @tab @tab X @tab fourcc: VCR1 -@item ATI VCR2 @tab @tab X @tab fourcc: VCR2 -@item Cirrus Logic AccuPak @tab @tab X @tab fourcc: CLJR -@item 4X Video @tab @tab X @tab Used in certain computer games. +@item Renderware TXD @tab @tab X + @tab Texture dictionaries used by the Renderware Engine. +@item RTjpeg @tab @tab X + @tab Video encoding used in NuppelVideo files. +@item Smacker video @tab @tab X + @tab Video encoding used in Smacker. +@item Snow @tab X @tab X + @tab experimental wavelet codec (fourcc: SNOW) @item Sony PlayStation MDEC @tab @tab X -@item id RoQ @tab X @tab X @tab Used in Quake III, Jedi Knight 2, other computer games. -@item Xan/WC3 @tab @tab X @tab Used in Wing Commander III .MVE files. -@item Interplay Video @tab @tab X @tab Used in Interplay .MVE files. -@item Apple Animation @tab X @tab X @tab fourcc: 'rle ' -@item Apple Graphics @tab @tab X @tab fourcc: 'smc ' -@item Apple Video @tab @tab X @tab fourcc: rpza -@item Apple QuickDraw @tab @tab X @tab fourcc: qdrw -@item Cinepak @tab @tab X -@item Microsoft RLE @tab @tab X -@item Microsoft Video-1 @tab @tab X +@item Sorenson Video 1 @tab X @tab X + @tab fourcc: SVQ1 +@item Sorenson Video 3 @tab @tab X + @tab fourcc: SVQ3 +@item Sunplus MJPEG @tab @tab X + @tab fourcc: SP5X +@item TechSmith Camtasia @tab @tab X + @tab fourcc: TSCC +@item Theora @tab X @tab X + @tab still experimental +@item THP @tab @tab X + @tab Used on the Nintendo GameCube. +@item Tiertex Seq video @tab @tab X + @tab Codec used in DOS CD-ROM FlashBack game. +@item VC-1 @tab @tab X +@item VMD Video @tab @tab X + @tab Used in Sierra VMD files. +@item VMware Video @tab @tab X + @tab Codec used in videos captured by VMware. @item Westwood VQA @tab @tab X -@item id Cinematic Video @tab @tab X @tab Used in Quake II. -@item Planar RGB @tab @tab X @tab fourcc: 8BPS -@item FLIC video @tab @tab X -@item Duck TrueMotion v1 @tab @tab X @tab fourcc: DUCK -@item Duck TrueMotion v2 @tab @tab X @tab fourcc: TM20 -@item VMD Video @tab @tab X @tab Used in Sierra VMD files. -@item MSZH @tab @tab X @tab Part of LCL -@item ZLIB @tab X @tab X @tab Part of LCL, encoder experimental -@item TechSmith Camtasia @tab @tab X @tab fourcc: TSCC -@item IBM Ultimotion @tab @tab X @tab fourcc: ULTI -@item Miro VideoXL @tab @tab X @tab fourcc: VIXL -@item QPEG @tab @tab X @tab fourccs: QPEG, Q1.0, Q1.1 -@item LOCO @tab @tab X @tab -@item Winnov WNV1 @tab @tab X @tab -@item Autodesk Animator Studio Codec @tab @tab X @tab fourcc: AASC -@item Fraps FPS1 @tab @tab X @tab -@item CamStudio @tab @tab X @tab fourcc: CSCD -@item American Laser Games Video @tab @tab X @tab Used in games like Mad Dog McCree -@item ZMBV @tab X @tab X @tab Encoder works only on PAL8 -@item AVS Video @tab @tab X @tab Video encoding used by the Creature Shock game. -@item Smacker Video @tab @tab X @tab Video encoding used in Smacker. -@item RTjpeg @tab @tab X @tab Video encoding used in NuppelVideo files. -@item KMVC @tab @tab X @tab Codec used in Worms games. -@item VMware Video @tab @tab X @tab Codec used in videos captured by VMware. -@item Cin Video @tab @tab X @tab Codec used in Delphine Software games. -@item Tiertex Seq Video @tab @tab X @tab Codec used in DOS CD-ROM FlashBack game. -@item DXA Video @tab @tab X @tab Codec originally used in Feeble Files game. -@item AVID DNxHD @tab X @tab X @tab aka SMPTE VC3 -@item C93 Video @tab @tab X @tab Codec used in Cyberia game. -@item THP @tab @tab X @tab Used on the Nintendo GameCube. -@item Bethsoft VID @tab @tab X @tab Used in some games from Bethesda Softworks. -@item Renderware TXD @tab @tab X @tab Texture dictionaries used by the Renderware Engine. -@item AMV @tab @tab X @tab Used in Chinese MP3 players. -@item Mimic @tab @tab X @tab Used in MSN Messenger Webcam streams. +@item Winnov WNV1 @tab @tab X +@item WMV7 @tab X @tab X +@item WMV8 @tab X @tab X +@item WMV9 @tab @tab X + @tab not completely working +@item Xan/WC3 @tab @tab X + @tab Used in Wing Commander III .MVE files. +@item ZLIB @tab X @tab X + @tab part of LCL, encoder experimental +@item ZMBV @tab X @tab X + @tab Encoder works only in PAL8. @end multitable @code{X} means that encoding (resp. decoding) is supported. @@ -267,86 +333,91 @@ following image formats are supported: @multitable @columnfractions .4 .1 .1 .1 .7 @item Supported Codec @tab Encoding @tab Decoding @tab Comments -@item MPEG audio layer 2 @tab IX @tab IX -@item MPEG audio layer 1/3 @tab X @tab IX -@tab MP3 encoding is supported through the external library LAME. -@item AC3 @tab IX @tab IX -@tab liba52 is used internally for decoding. -@item Vorbis @tab X @tab X -@item WMA V1/V2 @tab X @tab X -@item AAC @tab X @tab X -@tab Supported through the external library libfaac/libfaad. -@item Microsoft ADPCM @tab X @tab X -@item AMV IMA ADPCM @tab @tab X -@tab Used in AMV files -@item MS IMA ADPCM @tab X @tab X -@item QT IMA ADPCM @tab X @tab X -@item 4X IMA ADPCM @tab @tab X -@item G.726 ADPCM @tab X @tab X -@item Duck DK3 IMA ADPCM @tab @tab X -@tab Used in some Sega Saturn console games. -@item Duck DK4 IMA ADPCM @tab @tab X -@tab Used in some Sega Saturn console games. -@item Westwood Studios IMA ADPCM @tab @tab X -@tab Used in Westwood Studios games like Command and Conquer. -@item SMJPEG IMA ADPCM @tab @tab X -@tab Used in certain Loki game ports. -@item CD-ROM XA ADPCM @tab @tab X -@item CRI ADX ADPCM @tab X @tab X -@tab Used in Sega Dreamcast games. -@item Electronic Arts ADPCM @tab @tab X -@tab Used in various EA titles. -@item MAXIS EA ADPCM @tab @tab X -@tab Used in Sim City 3000. -@item Creative ADPCM @tab @tab X -@tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 -@item THP ADPCM @tab @tab X -@tab Used on the Nintendo GameCube. -@item RA144 @tab @tab X -@tab Real 14400 bit/s codec -@item RA288 @tab @tab X -@tab Real 28800 bit/s codec -@item RADnet @tab X @tab IX -@tab Real low bitrate AC3 codec, liba52 is used for decoding. -@item AMR-NB @tab X @tab X -@tab Supported through an external library. -@item AMR-WB @tab X @tab X -@tab Supported through an external library. -@item DV audio @tab @tab X -@item id RoQ DPCM @tab X @tab X -@tab Used in Quake III, Jedi Knight 2, other computer games. -@item Interplay MVE DPCM @tab @tab X -@tab Used in various Interplay computer games. -@item Xan DPCM @tab @tab X -@tab Used in Origin's Wing Commander IV AVI files. -@item Sierra Online DPCM @tab @tab X -@tab Used in Sierra Online game audio files. -@item Apple MACE 3 @tab @tab X -@item Apple MACE 6 @tab @tab X -@item FLAC lossless audio @tab X @tab X -@item Shorten lossless audio @tab @tab X -@item Apple lossless audio @tab @tab X -@tab QuickTime fourcc 'alac' -@item FFmpeg Sonic @tab X @tab X -@tab experimental lossy/lossless codec -@item Qdesign QDM2 @tab @tab X -@tab there are still some distortions -@item Real COOK @tab @tab X -@tab All versions except 5.1 are supported -@item DSP Group TrueSpeech @tab @tab X -@item True Audio (TTA) @tab @tab X -@item Smacker Audio @tab @tab X -@item WavPack Audio @tab @tab X -@item Cin Audio @tab @tab X -@tab Codec used in Delphine Software games. -@item Intel Music Coder @tab @tab X -@item Musepack @tab @tab X -@tab SV7 and SV8 are supported -@item DTS Coherent Audio @tab @tab X -@item ATRAC 3 @tab @tab X -@item Monkey's Audio @tab @tab X @tab Only versions 3.97-3.99 are supported -@item Nellymoser ASAO @tab @tab X -@item 8SVX Audio @tab @tab X +@item 4X IMA ADPCM @tab @tab X +@item 8SVX audio @tab @tab X +@item AAC @tab X @tab X + @tab Supported through the external library libfaac/libfaad. +@item AC-3 @tab IX @tab IX + @tab liba52 can be used alternatively for decoding. +@item AMR-NB @tab X @tab X + @tab Supported through an external library. +@item AMR-WB @tab X @tab X + @tab Supported through an external library. +@item AMV IMA ADPCM @tab @tab X + @tab Used in AMV files +@item Apple lossless audio @tab @tab X + @tab QuickTime fourcc 'alac' +@item Apple MACE 3 @tab @tab X +@item Apple MACE 6 @tab @tab X +@item ATRAC 3 @tab @tab X +@item CD-ROM XA ADPCM @tab @tab X +@item Cin audio @tab @tab X + @tab Codec used in Delphine Software International games. +@item Creative ADPCM @tab @tab X + @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 +@item CRI ADX ADPCM @tab X @tab X + @tab Used in Sega Dreamcast games. +@item DSP Group TrueSpeech @tab @tab X +@item DTS Coherent Audio @tab @tab X +@item Duck DK3 IMA ADPCM @tab @tab X + @tab Used in some Sega Saturn console games. +@item Duck DK4 IMA ADPCM @tab @tab X + @tab Used in some Sega Saturn console games. +@item DV audio @tab @tab X +@item Electronic Arts ADPCM @tab @tab X + @tab Used in various EA titles. +@item Sonic @tab X @tab X + @tab experimental codec +@item Sonic lossless @tab X @tab X + @tab experimental codec +@item FLAC lossless audio @tab X @tab X +@item G.726 ADPCM @tab X @tab X +@item id RoQ DPCM @tab X @tab X + @tab Used in Quake III, Jedi Knight 2, other computer games. +@item Intel Music Coder @tab @tab X +@item Interplay MVE DPCM @tab @tab X + @tab Used in various Interplay computer games. +@item MAXIS EA ADPCM @tab @tab X + @tab Used in Sim City 3000. +@item Microsoft ADPCM @tab X @tab X +@item MLP/TrueHD @tab @tab X + @tab Used in DVD-Audio and Blu-Ray discs. +@item Monkey's Audio @tab @tab X + @tab Only versions 3.97-3.99 are supported. +@item MPEG audio layer 1/3 @tab X @tab IX + @tab MP3 encoding is supported through the external library LAME. +@item MPEG audio layer 2 @tab IX @tab IX +@item MS IMA ADPCM @tab X @tab X +@item Musepack @tab @tab X + @tab SV7 and SV8 are supported. +@item Nellymoser ASAO @tab @tab X +@item Qdesign QDM2 @tab @tab X + @tab There are still some distortions. +@item QT IMA ADPCM @tab X @tab X +@item RA144 @tab @tab X + @tab Real 14400 bit/s codec +@item RA288 @tab @tab X + @tab Real 28800 bit/s codec +@item RADnet @tab X @tab IX + @tab real low bitrate AC-3 codec +@item Real COOK @tab @tab X + @tab All versions except 5.1 are supported. +@item Shorten @tab @tab X +@item Sierra Online DPCM @tab @tab X + @tab Used in Sierra Online game audio files. +@item Smacker audio @tab @tab X +@item SMJPEG IMA ADPCM @tab @tab X + @tab Used in certain Loki game ports. +@item THP ADPCM @tab @tab X + @tab Used on the Nintendo GameCube. +@item True Audio (TTA) @tab @tab X +@item Vorbis @tab X @tab X +@item WavPack @tab @tab X +@item Westwood Studios IMA ADPCM @tab @tab X + @tab Used in Westwood Studios games like Command and Conquer. +@item WMA v1/v2 @tab X @tab X +@item Xan DPCM @tab @tab X + @tab Used in Origin's Wing Commander IV AVI files. @end multitable @code{X} means that encoding (resp. decoding) is supported. @@ -835,12 +906,6 @@ should also be avoided if they don't make the code easier to understand. Incrementing the third component means a noteworthy binary compatible change (e.g. encoder bug fix that matters for the decoder). @item - If you add a new codec, remember to update the changelog, add it to - the supported codecs table in the documentation and bump the second - component of the @file{libavcodec} version number appropriately. If - it has a fourcc, add it to @file{libavformat/riff.c}, even if it - is only a decoder. -@item Compiler warnings indicate potential bugs or code with bad style. If a type of warning always points to correct and clean code, that warning should be disabled, not the code changed. @@ -886,6 +951,40 @@ and has no lrint()') Also please if you send several patches, send each patch as a separate mail, do not attach several unrelated patches to the same mail. +@section New codecs or formats checklist + +@enumerate +@item + Did you use av_cold for codec initialization and close functions? +@item + Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or + AVInputFormat/AVOutputFormat struct? +@item + Did you bump the minor version number in @file{avcodec.h} or + @file{avformat.h}? +@item + Did you register it in @file{allcodecs.c} or @file{allformats.c}? +@item + Did you add the CodecID to @file{avcodec.h}? +@item + If it has a fourcc, did you add it to @file{libavformat/riff.c}, + even if it is only a decoder? +@item + Did you add a rule to compile the appropriate files in the Makefile? + Remember to do this even if you're just adding a format to a file that is + already being compiled by some other rule, like a raw demuxer. +@item + Did you add an entry to the table of supported formats or codecs in the + documentation? +@item + Did you add an entry in the Changelog? +@item + If it depends on a parser or a library, did you add that dependency in + configure? +@item + Did you "svn add" the appropriate files before commiting? +@end enumerate + @section patch submission checklist @enumerate diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/ffmpeg.c b/src/plugins/thumbnailffmpeg/ffmpeg/ffmpeg.c @@ -85,6 +85,7 @@ static const OptionDef options[]; static AVFormatContext *input_files[MAX_FILES]; static int64_t input_files_ts_offset[MAX_FILES]; +static double input_files_ts_scale[MAX_FILES][MAX_STREAMS]; static int nb_input_files = 0; static AVFormatContext *output_files[MAX_FILES]; @@ -112,9 +113,8 @@ static int frame_bottomBand = 0; static int frame_leftBand = 0; static int frame_rightBand = 0; static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX}; -static AVRational frame_rate = (AVRational) {0,0}; +static AVRational frame_rate; static float video_qscale = 0; -static int video_qdiff = 3; static uint16_t *intra_matrix = NULL; static uint16_t *inter_matrix = NULL; #if 0 //experimental, (can be removed) @@ -129,7 +129,6 @@ static char *video_codec_name = NULL; static int video_codec_tag = 0; static int same_quality = 0; static int do_deinterlace = 0; -static int strict = 0; static int top_field_first = -1; static int me_threshold = 0; static int intra_dc_precision = 8; @@ -154,7 +153,7 @@ static char *subtitle_language = NULL; static float mux_preload= 0.5; static float mux_max_delay= 0.7; -static int64_t recording_time = 0; +static int64_t recording_time = INT64_MAX; static int64_t start_time = 0; static int64_t rec_timestamp = 0; static int64_t input_ts_offset = 0; @@ -174,7 +173,7 @@ static char *pass_logfilename = NULL; static int audio_stream_copy = 0; static int video_stream_copy = 0; static int subtitle_stream_copy = 0; -static int video_sync_method= 1; +static int video_sync_method= -1; static int audio_sync_method= 0; static float audio_drift_threshold= 0.1; static int copy_ts= 0; @@ -449,6 +448,11 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) else if (st->codec->codec_type == CODEC_TYPE_VIDEO && video_stream_copy) st->stream_copy = 1; + if(!st->codec->thread_count) + st->codec->thread_count = 1; + if(st->codec->thread_count>1) + avcodec_thread_init(st->codec, st->codec->thread_count); + if(st->codec->flags & CODEC_FLAG_BITEXACT) nopts = 1; } @@ -793,7 +797,7 @@ static void do_video_out(AVFormatContext *s, *frame_size = 0; - if(video_sync_method){ + if(video_sync_method>0 || (video_sync_method && av_q2d(enc->time_base) > 0.001)){ double vdelta; vdelta = get_sync_ipts(ost) / av_q2d(enc->time_base) - ost->sync_opts; //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c @@ -923,6 +927,7 @@ static void do_video_out(AVFormatContext *s, pkt.flags |= PKT_FLAG_KEY; write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); *frame_size = ret; + video_size += ret; //fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d", // enc->frame_number-1, enc->real_pict_num, ret, // enc->pict_type); @@ -1135,7 +1140,9 @@ static int output_packet(AVInputStream *ist, int ist_index, len = pkt->size; ptr = pkt->data; - while (len > 0) { + + //while we have more to decode or while the decoder did output something on EOF + while (len > 0 || (!pkt && ist->next_pts != ist->pts)) { handle_eof: ist->pts= ist->next_pts; @@ -1294,7 +1301,6 @@ static int output_packet(AVInputStream *ist, int ist_index, break; case CODEC_TYPE_VIDEO: do_video_out(os, ost, ist, &picture, &frame_size); - video_size += frame_size; if (vstats_filename && frame_size) do_video_stats(os, ost, frame_size); break; @@ -1333,10 +1339,10 @@ static int output_packet(AVInputStream *ist, int ist_index, else opkt.pts= AV_NOPTS_VALUE; - if (pkt->dts == AV_NOPTS_VALUE) - opkt.dts = av_rescale_q(ist->next_pts, AV_TIME_BASE_Q, ost->st->time_base); - else - opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); + if (pkt->dts == AV_NOPTS_VALUE) + opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base); + else + opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); opkt.flags= pkt->flags; @@ -1682,6 +1688,10 @@ static int av_encode(AVFormatContext **output_files, codec->time_base = ist->st->time_base; switch(codec->codec_type) { case CODEC_TYPE_AUDIO: + if(audio_volume != 256) { + fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n"); + av_exit(1); + } codec->sample_rate = icodec->sample_rate; codec->channels = icodec->channels; codec->frame_size = icodec->frame_size; @@ -2009,7 +2019,7 @@ static int av_encode(AVFormatContext **output_files, } /* finish if recording time exhausted */ - if (recording_time > 0 && opts_min >= (recording_time / 1000000.0)) + if (opts_min >= (recording_time / 1000000.0)) break; /* finish if limit size exhausted */ @@ -2043,6 +2053,13 @@ static int av_encode(AVFormatContext **output_files, if (pkt.pts != AV_NOPTS_VALUE) pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base); + if(input_files_ts_scale[file_index][pkt.stream_index]){ + if(pkt.pts != AV_NOPTS_VALUE) + pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index]; + if(pkt.dts != AV_NOPTS_VALUE) + pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index]; + } + // fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type); if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) { int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); @@ -2199,19 +2216,19 @@ static int opt_default(const char *opt, const char *arg){ for(type=0; type<CODEC_TYPE_NB; type++){ const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]); if(o2) - o = av_set_string(avctx_opts[type], opt, arg); + o = av_set_string2(avctx_opts[type], opt, arg, 1); } if(!o) - o = av_set_string(avformat_opts, opt, arg); + o = av_set_string2(avformat_opts, opt, arg, 1); if(!o) - o = av_set_string(sws_opts, opt, arg); + o = av_set_string2(sws_opts, opt, arg, 1); if(!o){ if(opt[0] == 'a') - o = av_set_string(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg); + o = av_set_string2(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1); else if(opt[0] == 'v') - o = av_set_string(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg); + o = av_set_string2(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1); else if(opt[0] == 's') - o = av_set_string(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg); + o = av_set_string2(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1); } if(!o) return -1; @@ -2489,21 +2506,6 @@ static void opt_qscale(const char *arg) } } -static void opt_qdiff(const char *arg) -{ - video_qdiff = atoi(arg); - if (video_qdiff < 0 || - video_qdiff > 31) { - fprintf(stderr, "qdiff must be >= 1 and <= 31\n"); - av_exit(1); - } -} - -static void opt_strict(const char *arg) -{ - strict= atoi(arg); -} - static void opt_top_field_first(const char *arg) { top_field_first= atoi(arg); @@ -2646,6 +2648,23 @@ static void opt_map_meta_data(const char *arg) m->in_file = strtol(p, &p, 0); } +static void opt_input_ts_scale(const char *arg) +{ + unsigned int stream; + double scale; + char *p; + + stream = strtol(arg, &p, 0); + if (*p) + p++; + scale= strtod(p, &p); + + if(stream >= MAX_STREAMS) + av_exit(1); + + input_files_ts_scale[nb_input_files][stream]= scale; +} + static int opt_recording_time(const char *opt, const char *arg) { recording_time = parse_time_or_die(opt, arg, 1); @@ -2700,7 +2719,7 @@ static void set_context_opts(void *ctx, void *opts_ctx, int flags) const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf)); /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */ if(str && ((opt->flags & flags) == flags)) - av_set_string(ctx, opt_names[i], str); + av_set_string2(ctx, opt_names[i], str, 1); } } @@ -2992,7 +3011,6 @@ static void new_video_stream(AVFormatContext *oc) if(inter_matrix) video_enc->inter_matrix = inter_matrix; - video_enc->max_qdiff = video_qdiff; video_enc->thread_count = thread_count; p= video_rc_override_string; for(i=0; p; i++){ @@ -3023,7 +3041,6 @@ static void new_video_stream(AVFormatContext *oc) video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4; video_enc->me_threshold= me_threshold; video_enc->intra_dc_precision= intra_dc_precision - 8; - video_enc->strict_std_compliance = strict; if (do_psnr) video_enc->flags|= CODEC_FLAG_PSNR; @@ -3065,7 +3082,6 @@ static void new_audio_stream(AVFormatContext *oc) audio_enc = st->codec; audio_enc->codec_type = CODEC_TYPE_AUDIO; - audio_enc->strict_std_compliance = strict; if(audio_codec_tag) audio_enc->codec_tag= audio_codec_tag; @@ -3646,7 +3662,14 @@ static int opt_preset(const char *opt, const char *arg) fprintf(stderr, "Preset file invalid\n"); av_exit(1); } - opt_default(tmp, tmp2); + if(!strcmp(tmp, "acodec")){ + opt_audio_codec(tmp2); + }else if(!strcmp(tmp, "vcodec")){ + opt_video_codec(tmp2); + }else if(!strcmp(tmp, "scodec")){ + opt_subtitle_codec(tmp2); + }else + opt_default(tmp, tmp2); } fclose(f); @@ -3669,6 +3692,7 @@ static const OptionDef options[] = { { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, // { "ss", OPT_FUNC2 | HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" }, { "itsoffset", OPT_FUNC2 | HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" }, + { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" }, { "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" }, { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp", "time" }, { "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" }, @@ -3676,6 +3700,7 @@ static const OptionDef options[] = { { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" }, { "genre", HAS_ARG | OPT_STRING, {(void*)&str_genre}, "set the genre", "string" }, { "album", HAS_ARG | OPT_STRING, {(void*)&str_album}, "set the album", "string" }, + { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" }, { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark}, "add timings for benchmarking" }, { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump}, @@ -3701,7 +3726,6 @@ static const OptionDef options[] = { { "b", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, { "vb", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, { "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[CODEC_TYPE_VIDEO]}, "set the number of video frames to record", "number" }, - { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" }, { "r", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, "set frame rate (Hz value, fraction or abbreviation)", "rate" }, { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" }, { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" }, @@ -3719,11 +3743,9 @@ static const OptionDef options[] = { { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" }, { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" }, { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" }, - { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantizer scale (VBR)", "q" }, { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" }, { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" }, { "me_threshold", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" }, - { "strict", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_strict}, "how strictly to follow the standards", "strictness" }, { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, "use same video quality as source (implies VBR)" }, { "pass", HAS_ARG | OPT_VIDEO, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" }, @@ -3793,6 +3815,9 @@ int main(int argc, char **argv) avdevice_register_all(); av_register_all(); + if(isatty(STDIN_FILENO)) + url_set_interrupt_cb(decode_interrupt_cb); + for(i=0; i<CODEC_TYPE_NB; i++){ avctx_opts[i]= avcodec_alloc_context2(i); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/ffserver.c b/src/plugins/thumbnailffmpeg/ffmpeg/ffserver.c @@ -77,7 +77,7 @@ enum HTTPState { RTSPSTATE_SEND_PACKET, }; -const char *http_state[] = { +static const char *http_state[] = { "HTTP_WAIT_REQUEST", "HTTP_SEND_HEADER", @@ -215,7 +215,7 @@ typedef struct FFStream { time_t pid_start; /* Of ffmpeg process */ char **child_argv; struct FFStream *next; - int bandwidth; /* bandwidth, in kbits/s */ + unsigned bandwidth; /* bandwidth, in kbits/s */ /* RTSP options */ char *rtsp_option; /* multicast specific */ @@ -292,11 +292,11 @@ static int ffserver_daemon; static int no_launch; static int need_to_start_children; -static int nb_max_connections; +static int nb_max_connections = 5; static int nb_connections; -static int max_bandwidth; -static int current_bandwidth; +static uint64_t max_bandwidth = 1000; +static uint64_t current_bandwidth; static int64_t cur_time; // Making this global saves on passing it around everywhere @@ -304,18 +304,6 @@ static AVRandomState random_state; static FILE *logfile = NULL; -static void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - - if (logfile) { - vfprintf(logfile, fmt, ap); - fflush(logfile); - } - va_end(ap); -} - static char *ctime1(char *buf2) { time_t ti; @@ -330,16 +318,48 @@ static char *ctime1(char *buf2) return buf2; } -static void log_connection(HTTPContext *c) +static void http_vlog(const char *fmt, va_list vargs) { - char buf2[32]; + static int print_prefix = 1; + if (logfile) { + if (print_prefix) { + char buf[32]; + ctime1(buf); + fprintf(logfile, "%s ", buf); + } + print_prefix = strstr(fmt, "\n") != NULL; + vfprintf(logfile, fmt, vargs); + fflush(logfile); + } +} + +void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...) +{ + va_list vargs; + va_start(vargs, fmt); + http_vlog(fmt, vargs); + va_end(vargs); +} + +static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs) +{ + static int print_prefix = 1; + AVClass *avc = ptr ? *(AVClass**)ptr : NULL; + if (level > av_log_level) + return; + if (print_prefix && avc) + http_log("[%s @ %p]", avc->item_name(ptr), ptr); + print_prefix = strstr(fmt, "\n") != NULL; + http_vlog(fmt, vargs); +} +static void log_connection(HTTPContext *c) +{ if (c->suppress_log) return; - http_log("%s - - [%s] \"%s %s %s\" %d %"PRId64"\n", - inet_ntoa(c->from_addr.sin_addr), - ctime1(buf2), c->method, c->url, + http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n", + inet_ntoa(c->from_addr.sin_addr), c->method, c->url, c->protocol, (c->http_error ? c->http_error : 200), c->data_count); } @@ -378,7 +398,7 @@ static void start_children(FFStream *feed) feed->pid = fork(); if (feed->pid < 0) { - fprintf(stderr, "Unable to create children\n"); + http_log("Unable to create children\n"); exit(1); } if (!feed->pid) { @@ -387,19 +407,6 @@ static void start_children(FFStream *feed) char *slash; int i; - for (i = 3; i < 256; i++) - close(i); - - if (!ffserver_debug) { - i = open("/dev/null", O_RDWR); - if (i) - dup2(i, 0); - dup2(i, 1); - dup2(i, 2); - if (i) - close(i); - } - av_strlcpy(pathname, my_program_name, sizeof(pathname)); slash = strrchr(pathname, '/'); @@ -409,6 +416,25 @@ static void start_children(FFStream *feed) slash++; strcpy(slash, "ffmpeg"); + http_log("Launch commandline: "); + http_log("%s ", pathname); + for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++) + http_log("%s ", feed->child_argv[i]); + http_log("\n"); + + for (i = 3; i < 256; i++) + close(i); + + if (!ffserver_debug) { + i = open("/dev/null", O_RDWR); + if (i != -1) { + dup2(i, 0); + dup2(i, 1); + dup2(i, 2); + close(i); + } + } + /* This is needed to make relative pathnames work */ chdir(my_program_dir); @@ -486,8 +512,8 @@ static void start_multicast(void) continue; if (open_input_stream(rtp_c, "") < 0) { - fprintf(stderr, "Could not open input stream for stream '%s'\n", - stream->filename); + http_log("Could not open input stream for stream '%s'\n", + stream->filename); continue; } @@ -497,8 +523,8 @@ static void start_multicast(void) dest_addr.sin_port = htons(stream->multicast_port + 2 * stream_index); if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) { - fprintf(stderr, "Could not open output stream '%s/streamid=%d'\n", - stream->filename, stream_index); + http_log("Could not open output stream '%s/streamid=%d'\n", + stream->filename, stream_index); exit(1); } } @@ -512,36 +538,46 @@ static void start_multicast(void) /* main loop of the http server */ static int http_server(void) { - int server_fd, ret, rtsp_server_fd, delay, delay1; + int server_fd = 0, rtsp_server_fd = 0; + int ret, delay, delay1; struct pollfd poll_table[HTTP_MAX_CONNECTIONS + 2], *poll_entry; HTTPContext *c, *c_next; - server_fd = socket_open_listen(&my_http_addr); - if (server_fd < 0) - return -1; + if (my_http_addr.sin_port) { + server_fd = socket_open_listen(&my_http_addr); + if (server_fd < 0) + return -1; + } + + if (my_rtsp_addr.sin_port) { + rtsp_server_fd = socket_open_listen(&my_rtsp_addr); + if (rtsp_server_fd < 0) + return -1; + } - rtsp_server_fd = socket_open_listen(&my_rtsp_addr); - if (rtsp_server_fd < 0) + if (!rtsp_server_fd && !server_fd) { + http_log("HTTP and RTSP disabled.\n"); return -1; + } http_log("ffserver started.\n"); start_children(first_feed); - first_http_ctx = NULL; - nb_connections = 0; - start_multicast(); for(;;) { poll_entry = poll_table; - poll_entry->fd = server_fd; - poll_entry->events = POLLIN; - poll_entry++; - - poll_entry->fd = rtsp_server_fd; - poll_entry->events = POLLIN; - poll_entry++; + if (server_fd) { + poll_entry->fd = server_fd; + poll_entry->events = POLLIN; + poll_entry++; + } + if (rtsp_server_fd) { + poll_entry->fd = rtsp_server_fd; + poll_entry->events = POLLIN; + poll_entry++; + } /* wait for events on each HTTP handle */ c = first_http_ctx; @@ -620,13 +656,17 @@ static int http_server(void) } poll_entry = poll_table; - /* new HTTP connection request ? */ - if (poll_entry->revents & POLLIN) - new_connection(server_fd, 0); - poll_entry++; - /* new RTSP connection request ? */ - if (poll_entry->revents & POLLIN) - new_connection(rtsp_server_fd, 1); + if (server_fd) { + /* new HTTP connection request ? */ + if (poll_entry->revents & POLLIN) + new_connection(server_fd, 0); + poll_entry++; + } + if (rtsp_server_fd) { + /* new RTSP connection request ? */ + if (poll_entry->revents & POLLIN) + new_connection(rtsp_server_fd, 1); + } } } @@ -654,8 +694,10 @@ static void new_connection(int server_fd, int is_rtsp) len = sizeof(from_addr); fd = accept(server_fd, (struct sockaddr *)&from_addr, &len); - if (fd < 0) + if (fd < 0) { + http_log("error during accept %s\n", strerror(errno)); return; + } ff_socket_nonblock(fd, 1); /* XXX: should output a warning page when coming @@ -752,6 +794,7 @@ static void close_connection(HTTPContext *c) /* prepare header */ if (url_open_dyn_buf(&ctx->pb) >= 0) { av_write_trailer(ctx); + av_freep(&c->pb_buffer); url_close_dyn_buf(ctx->pb, &c->pb_buffer); } } @@ -1301,6 +1344,7 @@ static int http_parse_request(HTTPContext *c) /* If already streaming this feed, do not let start another feeder. */ if (stream->feed_opened) { snprintf(msg, sizeof(msg), "This feed is already being received."); + http_log("feed %s already being received\n", stream->feed_filename); goto send_error; } @@ -1315,7 +1359,7 @@ static int http_parse_request(HTTPContext *c) q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<html><head><title>Too busy</title></head><body>\r\n"); q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<p>The server is too busy to serve your request at this time.</p>\r\n"); - q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<p>The bandwidth being served (including your stream) is %dkbit/sec, and this exceeds the limit of %dkbit/sec.</p>\r\n", + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<p>The bandwidth being served (including your stream) is %lldkbit/sec, and this exceeds the limit of %lldkbit/sec.</p>\r\n", current_bandwidth, max_bandwidth); q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</body></html>\r\n"); @@ -1611,7 +1655,7 @@ static void compute_status(HTTPContext *c) url_fprintf(pb, "\r\n"); url_fprintf(pb, "<HEAD><TITLE>%s Status</TITLE>\n", program_name); - if (c->stream->feed_filename) + if (c->stream->feed_filename[0]) url_fprintf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename); url_fprintf(pb, "</HEAD>\n<BODY>"); url_fprintf(pb, "<H1>%s Status</H1>\n", program_name); @@ -1652,8 +1696,7 @@ static void compute_status(HTTPContext *c) stream->conns_served); fmt_bytecount(pb, stream->bytes_served); switch(stream->stream_type) { - case STREAM_TYPE_LIVE: - { + case STREAM_TYPE_LIVE: { int audio_bit_rate = 0; int video_bit_rate = 0; const char *audio_codec_name = ""; @@ -1811,7 +1854,7 @@ static void compute_status(HTTPContext *c) url_fprintf(pb, "Number of connections: %d / %d<BR>\n", nb_connections, nb_max_connections); - url_fprintf(pb, "Bandwidth in use: %dk / %dk<BR>\n", + url_fprintf(pb, "Bandwidth in use: %lldk / %lldk<BR>\n", current_bandwidth, max_bandwidth); url_fprintf(pb, "<TABLE>\n"); @@ -1891,13 +1934,11 @@ static int open_input_stream(HTTPContext *c, const char *info) strcpy(input_filename, c->stream->feed->feed_filename); buf_size = FFM_PACKET_SIZE; /* compute position (absolute time) */ - if (find_info_tag(buf, sizeof(buf), "date", info)) - { + if (find_info_tag(buf, sizeof(buf), "date", info)) { stream_pos = parse_date(buf, 0); if (stream_pos == INT64_MIN) return -1; - } - else if (find_info_tag(buf, sizeof(buf), "buffer", info)) { + } else if (find_info_tag(buf, sizeof(buf), "buffer", info)) { int prebuffer = strtol(buf, 0, 10); stream_pos = av_gettime() - prebuffer * (int64_t)1000000; } else @@ -1906,13 +1947,11 @@ static int open_input_stream(HTTPContext *c, const char *info) strcpy(input_filename, c->stream->feed_filename); buf_size = 0; /* compute position (relative time) */ - if (find_info_tag(buf, sizeof(buf), "date", info)) - { + if (find_info_tag(buf, sizeof(buf), "date", info)) { stream_pos = parse_date(buf, 1); if (stream_pos == INT64_MIN) return -1; - } - else + } else stream_pos = 0; } if (input_filename[0] == '\0') @@ -1950,7 +1989,7 @@ static int open_input_stream(HTTPContext *c, const char *info) #if 1 if (c->fmt_in->iformat->read_seek) - c->fmt_in->iformat->read_seek(c->fmt_in, 0, stream_pos, 0); + av_seek_frame(c->fmt_in, -1, stream_pos, 0); #endif /* set the start time (needed for maxtime and RTP packet timing) */ c->start_time = cur_time; @@ -2000,14 +2039,10 @@ static int http_prepare_data(HTTPContext *c) av_strlcpy(c->fmt_ctx.title, c->stream->title, sizeof(c->fmt_ctx.title)); - /* open output stream by using specified codecs */ - c->fmt_ctx.oformat = c->stream->fmt; - c->fmt_ctx.nb_streams = c->stream->nb_streams; - for(i=0;i<c->fmt_ctx.nb_streams;i++) { + for(i=0;i<c->stream->nb_streams;i++) { AVStream *st; AVStream *src; st = av_mallocz(sizeof(AVStream)); - st->codec= avcodec_alloc_context(); c->fmt_ctx.streams[i] = st; /* if file or feed, then just take streams from FFStream struct */ if (!c->stream->feed || @@ -2021,6 +2056,10 @@ static int http_prepare_data(HTTPContext *c) st->codec->frame_number = 0; /* XXX: should be done in AVStream, not in codec */ } + /* set output format parameters */ + c->fmt_ctx.oformat = c->stream->fmt; + c->fmt_ctx.nb_streams = c->stream->nb_streams; + c->got_key_frame = 0; /* prepare header and save header data in a stream */ @@ -2030,6 +2069,14 @@ static int http_prepare_data(HTTPContext *c) } c->fmt_ctx.pb->is_streamed = 1; + /* + * HACK to avoid mpeg ps muxer to spit many underflow errors + * Default value from FFmpeg + * Try to set it use configuration option + */ + c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); + c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); + av_set_parameters(&c->fmt_ctx, NULL); if (av_write_header(&c->fmt_ctx) < 0) { http_log("Error writing output header\n"); @@ -2111,19 +2158,18 @@ static int http_prepare_data(HTTPContext *c) } } else { AVCodecContext *codec; - + AVStream *ist, *ost; send_it: + ist = c->fmt_in->streams[source_index]; /* specific handling for RTP: we use several output stream (one for each RTP connection). XXX: need more abstract handling */ if (c->is_packetized) { - AVStream *st; /* compute send time and duration */ - st = c->fmt_in->streams[pkt.stream_index]; - c->cur_pts = av_rescale_q(pkt.dts, st->time_base, AV_TIME_BASE_Q); - if (st->start_time != AV_NOPTS_VALUE) - c->cur_pts -= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); - c->cur_frame_duration = av_rescale_q(pkt.duration, st->time_base, AV_TIME_BASE_Q); + c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q); + if (ist->start_time != AV_NOPTS_VALUE) + c->cur_pts -= av_rescale_q(ist->start_time, ist->time_base, AV_TIME_BASE_Q); + c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q); #if 0 printf("index=%d pts=%0.3f duration=%0.6f\n", pkt.stream_index, @@ -2162,15 +2208,14 @@ static int http_prepare_data(HTTPContext *c) /* XXX: potential leak */ return -1; } - c->fmt_ctx.pb->is_streamed = 1; + ost = ctx->streams[pkt.stream_index]; + + ctx->pb->is_streamed = 1; if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, - c->fmt_in->streams[source_index]->time_base, - ctx->streams[pkt.stream_index]->time_base); + pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base); if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, - c->fmt_in->streams[source_index]->time_base, - ctx->streams[pkt.stream_index]->time_base); + pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base); + pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base); if (av_write_frame(ctx, &pkt) < 0) { http_log("Error writing frame to output\n"); c->state = HTTPSTATE_SEND_DATA_TRAILER; @@ -2431,41 +2476,46 @@ static int http_receive_data(HTTPContext *c) } } else { /* We have a header in our hands that contains useful data */ - AVFormatContext s; + AVFormatContext *s = NULL; + ByteIOContext *pb; AVInputFormat *fmt_in; int i; - memset(&s, 0, sizeof(s)); - - url_open_buf(&s.pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY); - s.pb->is_streamed = 1; - /* use feed output format name to find corresponding input format */ fmt_in = av_find_input_format(feed->fmt->name); if (!fmt_in) goto fail; - if (fmt_in->priv_data_size > 0) { - s.priv_data = av_mallocz(fmt_in->priv_data_size); - if (!s.priv_data) - goto fail; - } else - s.priv_data = NULL; + url_open_buf(&pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY); + pb->is_streamed = 1; - if (fmt_in->read_header(&s, 0) < 0) { - av_freep(&s.priv_data); + if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) { + av_free(pb); goto fail; } /* Now we have the actual streams */ - if (s.nb_streams != feed->nb_streams) { - av_freep(&s.priv_data); + if (s->nb_streams != feed->nb_streams) { + av_close_input_stream(s); + av_free(pb); goto fail; } - for (i = 0; i < s.nb_streams; i++) - memcpy(feed->streams[i]->codec, - s.streams[i]->codec, sizeof(AVCodecContext)); - av_freep(&s.priv_data); + + for (i = 0; i < s->nb_streams; i++) { + AVStream *fst = feed->streams[i]; + AVStream *st = s->streams[i]; + memcpy(fst->codec, st->codec, sizeof(AVCodecContext)); + if (fst->codec->extradata_size) { + fst->codec->extradata = av_malloc(fst->codec->extradata_size); + if (!fst->codec->extradata) + goto fail; + memcpy(fst->codec->extradata, st->codec->extradata, + fst->codec->extradata_size); + } + } + + av_close_input_stream(s); + av_free(pb); } c->buffer_ptr = c->buffer; } @@ -3088,7 +3138,6 @@ static int rtp_new_av_stream(HTTPContext *c, char *ipaddr; URLContext *h = NULL; uint8_t *dummy_buf; - char buf2[32]; int max_packet_size; /* now we can open the relevant output stream */ @@ -3149,9 +3198,8 @@ static int rtp_new_av_stream(HTTPContext *c, goto fail; } - http_log("%s:%d - - [%s] \"PLAY %s/streamid=%d %s\"\n", + http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n", ipaddr, ntohs(dest_addr->sin_port), - ctime1(buf2), c->stream->filename, stream_index, c->protocol); /* normally, no packets should be output here, but the packet size may be checked */ @@ -3395,7 +3443,7 @@ static void build_feed_streams(void) if (sf->index != ss->index || sf->id != ss->id) { - printf("Index & Id do not match for stream %d (%s)\n", + http_log("Index & Id do not match for stream %d (%s)\n", i, feed->feed_filename); matches = 0; } else { @@ -3406,28 +3454,28 @@ static void build_feed_streams(void) #define CHECK_CODEC(x) (ccf->x != ccs->x) if (CHECK_CODEC(codec) || CHECK_CODEC(codec_type)) { - printf("Codecs do not match for stream %d\n", i); + http_log("Codecs do not match for stream %d\n", i); matches = 0; } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) { - printf("Codec bitrates do not match for stream %d\n", i); + http_log("Codec bitrates do not match for stream %d\n", i); matches = 0; } else if (ccf->codec_type == CODEC_TYPE_VIDEO) { if (CHECK_CODEC(time_base.den) || CHECK_CODEC(time_base.num) || CHECK_CODEC(width) || CHECK_CODEC(height)) { - printf("Codec width, height and framerate do not match for stream %d\n", i); + http_log("Codec width, height and framerate do not match for stream %d\n", i); matches = 0; } } else if (ccf->codec_type == CODEC_TYPE_AUDIO) { if (CHECK_CODEC(sample_rate) || CHECK_CODEC(channels) || CHECK_CODEC(frame_size)) { - printf("Codec sample_rate, channels, frame_size do not match for stream %d\n", i); + http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i); matches = 0; } } else { - printf("Unknown codec type\n"); + http_log("Unknown codec type\n"); matches = 0; } } @@ -3435,17 +3483,17 @@ static void build_feed_streams(void) break; } } else - printf("Deleting feed file '%s' as stream counts differ (%d != %d)\n", + http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n", feed->feed_filename, s->nb_streams, feed->nb_streams); av_close_input_file(s); } else - printf("Deleting feed file '%s' as it appears to be corrupt\n", + http_log("Deleting feed file '%s' as it appears to be corrupt\n", feed->feed_filename); if (!matches) { if (feed->readonly) { - printf("Unable to delete feed file '%s' as it is marked readonly\n", + http_log("Unable to delete feed file '%s' as it is marked readonly\n", feed->feed_filename); exit(1); } @@ -3456,15 +3504,15 @@ static void build_feed_streams(void) AVFormatContext s1, *s = &s1; if (feed->readonly) { - printf("Unable to create feed file '%s' as it is marked readonly\n", + http_log("Unable to create feed file '%s' as it is marked readonly\n", feed->feed_filename); exit(1); } /* only write the header of the ffm file */ if (url_fopen(&s->pb, feed->feed_filename, URL_WRONLY) < 0) { - fprintf(stderr, "Could not open output feed file '%s'\n", - feed->feed_filename); + http_log("Could not open output feed file '%s'\n", + feed->feed_filename); exit(1); } s->oformat = feed->fmt; @@ -3476,7 +3524,7 @@ static void build_feed_streams(void) } av_set_parameters(s, NULL); if (av_write_header(s) < 0) { - fprintf(stderr, "Container doesn't supports the required parameters\n"); + http_log("Container doesn't supports the required parameters\n"); exit(1); } /* XXX: need better api */ @@ -3486,7 +3534,7 @@ static void build_feed_streams(void) /* get feed size and write index */ fd = open(feed->feed_filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "Could not open output feed file '%s'\n", + http_log("Could not open output feed file '%s'\n", feed->feed_filename); exit(1); } @@ -3504,7 +3552,8 @@ static void build_feed_streams(void) /* compute the bandwidth used by each stream */ static void compute_bandwidth(void) { - int bandwidth, i; + unsigned bandwidth; + int i; FFStream *stream; for(stream = first_stream; stream != NULL; stream = stream->next) { @@ -3683,7 +3732,7 @@ static int opt_default(const char *opt, const char *arg, const AVOption *o = NULL; const AVOption *o2 = av_find_opt(avctx, opt, NULL, type, type); if(o2) - o = av_set_string(avctx, opt, arg); + o = av_set_string2(avctx, opt, arg, 1); if(!o) return -1; return 0; @@ -3776,16 +3825,18 @@ static int parse_ffconfig(const char *filename) nb_max_connections = val; } } else if (!strcasecmp(cmd, "MaxBandwidth")) { + int64_t llval; get_arg(arg, sizeof(arg), &p); - val = atoi(arg); - if (val < 10 || val > 100000) { + llval = atoll(arg); + if (llval < 10 || llval > 10000000) { fprintf(stderr, "%s:%d: Invalid MaxBandwidth: %s\n", filename, line_num, arg); errors++; } else - max_bandwidth = val; + max_bandwidth = llval; } else if (!strcasecmp(cmd, "CustomLog")) { - get_arg(logfilename, sizeof(logfilename), &p); + if (!ffserver_debug) + get_arg(logfilename, sizeof(logfilename), &p); } else if (!strcasecmp(cmd, "<Feed")) { /*********************************************/ /* Feed related options */ @@ -3835,15 +3886,6 @@ static int parse_ffconfig(const char *filename) (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : inet_ntoa(my_http_addr.sin_addr), ntohs(my_http_addr.sin_port), feed->filename); - - if (ffserver_debug) - { - int j; - fprintf(stdout, "Launch commandline: "); - for (j = 0; j <= i; j++) - fprintf(stdout, "%s ", feed->child_argv[j]); - fprintf(stdout, "\n"); - } } } else if (!strcasecmp(cmd, "ReadOnlyFile")) { if (feed) { @@ -3939,25 +3981,25 @@ static int parse_ffconfig(const char *filename) } else if (!strcasecmp(cmd, "Format")) { get_arg(arg, sizeof(arg), &p); if (stream) { - if (!strcmp(arg, "status")) { - stream->stream_type = STREAM_TYPE_STATUS; - stream->fmt = NULL; - } else { - stream->stream_type = STREAM_TYPE_LIVE; - /* jpeg cannot be used here, so use single frame jpeg */ - if (!strcmp(arg, "jpeg")) - strcpy(arg, "mjpeg"); - stream->fmt = guess_stream_format(arg, NULL, NULL); - if (!stream->fmt) { - fprintf(stderr, "%s:%d: Unknown Format: %s\n", - filename, line_num, arg); - errors++; + if (!strcmp(arg, "status")) { + stream->stream_type = STREAM_TYPE_STATUS; + stream->fmt = NULL; + } else { + stream->stream_type = STREAM_TYPE_LIVE; + /* jpeg cannot be used here, so use single frame jpeg */ + if (!strcmp(arg, "jpeg")) + strcpy(arg, "mjpeg"); + stream->fmt = guess_stream_format(arg, NULL, NULL); + if (!stream->fmt) { + fprintf(stderr, "%s:%d: Unknown Format: %s\n", + filename, line_num, arg); + errors++; + } + } + if (stream->fmt) { + audio_id = stream->fmt->audio_codec; + video_id = stream->fmt->video_codec; } - } - if (stream->fmt) { - audio_id = stream->fmt->audio_codec; - video_id = stream->fmt->video_codec; - } } } else if (!strcasecmp(cmd, "InputFormat")) { get_arg(arg, sizeof(arg), &p); @@ -4386,6 +4428,7 @@ static void opt_debug() { ffserver_debug = 1; ffserver_daemon = 0; + logfilename[0] = '-'; } static void opt_show_help(void) @@ -4427,21 +4470,6 @@ int main(int argc, char **argv) av_init_random(av_gettime() + (getpid() << 16), &random_state); - /* address on which the server will handle HTTP connections */ - my_http_addr.sin_family = AF_INET; - my_http_addr.sin_port = htons (8080); - my_http_addr.sin_addr.s_addr = htonl (INADDR_ANY); - - /* address on which the server will handle RTSP connections */ - my_rtsp_addr.sin_family = AF_INET; - my_rtsp_addr.sin_port = htons (5454); - my_rtsp_addr.sin_addr.s_addr = htonl (INADDR_ANY); - - nb_max_connections = 5; - max_bandwidth = 1000; - first_stream = NULL; - logfilename[0] = '\0'; - memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = handle_child_exit; sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART; @@ -4452,6 +4480,15 @@ int main(int argc, char **argv) exit(1); } + /* open log file if needed */ + if (logfilename[0] != '\0') { + if (!strcmp(logfilename, "-")) + logfile = stdout; + else + logfile = fopen(logfilename, "a"); + av_log_set_callback(http_av_log); + } + build_file_streams(); build_feed_streams(); @@ -4472,7 +4509,6 @@ int main(int argc, char **argv) } else { /* child */ setsid(); - chdir("/"); close(0); open("/dev/null", O_RDWR); if (strcmp(logfilename, "-") != 0) { @@ -4487,16 +4523,11 @@ int main(int argc, char **argv) /* signal init */ signal(SIGPIPE, SIG_IGN); - /* open log file if needed */ - if (logfilename[0] != '\0') { - if (!strcmp(logfilename, "-")) - logfile = stdout; - else - logfile = fopen(logfilename, "a"); - } + if (ffserver_daemon) + chdir("/"); if (http_server() < 0) { - fprintf(stderr, "Could not start server\n"); + http_log("Could not start server\n"); exit(1); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/Makefile b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/Makefile @@ -61,6 +61,7 @@ OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o OBJS-$(CONFIG_DVVIDEO_DECODER) += dv.o OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o OBJS-$(CONFIG_DXA_DECODER) += dxa.o +OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o @@ -107,7 +108,9 @@ OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpeg.o mpegvideo_enc.o motion_est.o ratecontrol.o mpeg12data.o mpegvideo.o OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o mjpegdec.o mjpeg.o +OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o +OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o mpegaudiodata.o OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o @@ -148,7 +151,7 @@ OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o -OBJS-$(CONFIG_RA_144_DECODER) += ra144.o +OBJS-$(CONFIG_RA_144_DECODER) += ra144.o acelp_filters.o OBJS-$(CONFIG_RA_288_DECODER) += ra288.o OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o @@ -194,7 +197,7 @@ OBJS-$(CONFIG_TTA_DECODER) += tta.o OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o OBJS-$(CONFIG_ULTI_DECODER) += ulti.o OBJS-$(CONFIG_VB_DECODER) += vb.o -OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o +OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o mpegvideo.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o @@ -217,7 +220,7 @@ OBJS-$(CONFIG_WMV1_DECODER) += h263dec.o h263.o mpeg12data.o mpegvide OBJS-$(CONFIG_WMV1_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o mpeg12data.o mpegvideo.o error_resilience.o OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o msmpeg4.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o mpeg12data.o mpegvideo.o error_resilience.o OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o mpeg12data.o mpegvideo.o error_resilience.o -OBJS-$(CONFIG_WMV3_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o +OBJS-$(CONFIG_WMV3_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o mpegvideo.o OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o @@ -230,77 +233,80 @@ OBJS-$(CONFIG_ZLIB_ENCODER) += lclenc.o OBJS-$(CONFIG_ZMBV_DECODER) += zmbv.o OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o -OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S8_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S16LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S16LE_PLANAR_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S24DAUD_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24DAUD_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S32BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U8_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U8_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U16BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U16BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U16LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U16LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U24BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U24BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U24LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U24LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U32BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_ZORK_ENCODER) += pcm.o - -OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o -OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o -OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o -OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o -OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o +OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_DVD_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S8_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_PLANAR_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24DAUD_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24DAUD_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S32BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U8_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U8_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U16BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U16BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U16LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U16LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U24BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U24BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U32BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U32BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_ZORK_ENCODER) += pcm.o + +OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o +OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o +OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o +OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o +OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o # libavformat dependencies OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o @@ -347,17 +353,18 @@ OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o mpegaudiodecheader. OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o - -OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o -OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o -OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o -OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o -OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o -OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o -OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o mpegaudiodata.o -OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o -OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o -OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o +OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o + +OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o +OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o +OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o +OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o +OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o +OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o +OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o mpegaudiodata.o +OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o +OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o +OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o OBJS-$(HAVE_BEOSTHREADS) += beosthread.o OBJS-$(HAVE_OS2THREADS) += os2thread.o diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/aac_ac3_parser.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/aac_ac3_parser.h @@ -28,6 +28,7 @@ #include "parser.h" typedef struct AACAC3ParseContext { + ParseContext pc; int frame_size; int header_size; int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info, @@ -38,7 +39,6 @@ typedef struct AACAC3ParseContext { int bit_rate; int samples; - ParseContext pc; int remaining_size; uint64_t state; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ac3_parser.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ac3_parser.c @@ -192,5 +192,5 @@ AVCodecParser ac3_parser = { sizeof(AACAC3ParseContext), ac3_parse_init, ff_aac_ac3_parse, - NULL, + ff_parse_close, }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ac3dec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ac3dec.c @@ -437,7 +437,7 @@ static void get_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_grou tbap = bap[i]; switch (tbap) { case 0: - coeffs[i] = (av_random(&s->dith_state) & 0x7FFFFF) - 4194304; + coeffs[i] = (av_random(&s->dith_state) & 0x7FFFFF) - 0x400000; break; case 1: @@ -753,8 +753,8 @@ static int ac3_parse_audio_block(AC3DecodeContext *s, int blk) /* coupling strategy */ if (get_bits1(gbc)) { memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); - cpl_in_use = get_bits1(gbc); - if (cpl_in_use) { + s->cpl_in_use[blk] = get_bits1(gbc); + if (s->cpl_in_use[blk]) { /* coupling in use */ int cpl_begin_freq, cpl_end_freq; @@ -797,9 +797,9 @@ static int ac3_parse_audio_block(AC3DecodeContext *s, int blk) av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must be present in block 0\n"); return -1; } else { - cpl_in_use = s->cpl_in_use[blk-1]; + s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; } - s->cpl_in_use[blk] = cpl_in_use; + cpl_in_use = s->cpl_in_use[blk]; /* coupling coordinates */ if (cpl_in_use) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ac3enc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ac3enc.c @@ -490,7 +490,7 @@ static int compute_bit_allocation(AC3EncodeContext *s, uint8_t bap1[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50]; - static int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; + static const int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; /* init default parameters */ s->slow_decay_code = 2; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_filters.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_filters.c @@ -116,13 +116,18 @@ int ff_acelp_lp_synthesis_filter( const int16_t* in, int buffer_length, int filter_length, - int stop_on_overflow) + int stop_on_overflow, + int rounder) { int i,n; + // These two lines are to avoid a -1 subtraction in the main loop + filter_length++; + filter_coeffs--; + for(n=0; n<buffer_length; n++) { - int sum = 0x800; + int sum = rounder; for(i=1; i<filter_length; i++) sum -= filter_coeffs[i] * out[n-i]; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_filters.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_filters.h @@ -90,7 +90,7 @@ extern const int16_t ff_acelp_interp_filter[61]; * * filter_coeffs contains coefficients of the positive half of the symmetric * interpolation filter. filter_coeffs[0] should the central (unpaired) coefficient. - * See ff_acelp_interp_filter fot example. + * See ff_acelp_interp_filter for an example. * */ void ff_acelp_interpolate( @@ -125,9 +125,10 @@ void ff_acelp_convolve_circ( * \param filter_coeffs filter coefficients (-0x8000 <= (3.12) < 0x8000) * \param in input signal * \param buffer_length amount of data to process - * \param filter_length filter length (11 for 10th order LP filter) + * \param filter_length filter length (10 for 10th order LP filter) * \param stop_on_overflow 1 - return immediately if overflow occurs * 0 - ignore overflows + * \param rounder the amount to add for rounding (usually 0x800 or 0xfff) * * \return 1 if overflow occurred, 0 - otherwise * @@ -142,7 +143,8 @@ int ff_acelp_lp_synthesis_filter( const int16_t* in, int buffer_length, int filter_length, - int stop_on_overflow); + int stop_on_overflow, + int rounder); /** * \brief Calculates coefficients of weighted A(z/weight) filter. diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_math.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_math.h @@ -51,23 +51,21 @@ int ff_exp2(uint16_t power); int ff_log2(uint32_t value); /** - * \brief Calculates sum of array element multiplications - * \param speech input data array + * \brief returns the dot product + * \param a input data array + * \param b input data array * \param length number of elements - * \param offset offset for calculation of sum of s[i]*s[i+offset] - * \param shift right shift by this value will be done before multiplication + * \param shift right shift by this value will be done after multiplication * - * \return sum of multiplications - * - * \note array must be at least length+offset long! + * \return dot product = sum of elementwise products */ -static int sum_of_squares(const int16_t* speech, int length, int offset, int shift) +static int dot_product(const int16_t* a, const int16_t* b, int length, int shift) { - const int16_t* speech_end; int sum = 0; + int i; - for(speech_end=speech+length; speech<speech_end; speech++) - sum += (speech[0] * speech[offset]) >> shift; + for(i=0; i<length; i++) + sum += (a[i] * b[i]) >> shift; return sum; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_pitch_delay.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_pitch_delay.c @@ -0,0 +1,119 @@ +/* + * gain code, gain pitch and pitch delay decoding + * + * Copyright (c) 2008 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "acelp_pitch_delay.h" +#include "acelp_math.h" + +int ff_acelp_decode_8bit_to_1st_delay3(int ac_index) +{ + ac_index += 58; + if(ac_index > 254) + ac_index = 3 * ac_index - 510; + return ac_index; +} + +int ff_acelp_decode_4bit_to_2nd_delay3( + int ac_index, + int pitch_delay_min) +{ + if(ac_index < 4) + return 3 * (ac_index + pitch_delay_min); + else if(ac_index < 12) + return 3 * pitch_delay_min + ac_index + 6; + else + return 3 * (ac_index + pitch_delay_min) - 18; +} + +int ff_acelp_decode_5_6_bit_to_2nd_delay3( + int ac_index, + int pitch_delay_min) +{ + return 3 * pitch_delay_min + ac_index - 2; +} + +int ff_acelp_decode_9bit_to_1st_delay6(int ac_index) +{ + if(ac_index < 463) + return ac_index + 105; + else + return 6 * (ac_index - 368); +} +int ff_acelp_decode_6bit_to_2nd_delay6( + int ac_index, + int pitch_delay_min) +{ + return 6 * pitch_delay_min + ac_index - 3; +} + +void ff_acelp_update_past_gain( + int16_t* quant_energy, + int gain_corr_factor, + int log2_ma_pred_order, + int erasure) +{ + int i; + int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10) + + for(i=(1 << log2_ma_pred_order) - 1; i>0; i--) + { + avg_gain += quant_energy[i-1]; + quant_energy[i] = quant_energy[i-1]; + } + + if(erasure) + quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10) + else + quant_energy[0] = (6165 * ((ff_log2(gain_corr_factor) >> 2) - (13 << 13))) >> 13; +} + +int16_t ff_acelp_decode_gain_code( + int gain_corr_factor, + const int16_t* fc_v, + int mr_energy, + const int16_t* quant_energy, + const int16_t* ma_prediction_coeff, + int subframe_size, + int ma_pred_order) +{ + int i; + + mr_energy <<= 10; + + for(i=0; i<ma_pred_order; i++) + mr_energy += quant_energy[i] * ma_prediction_coeff[i]; + +#ifdef G729_BITEXACT + mr_energy += (((-6165LL * ff_log2(dot_product(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff); + + mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23) + + return bidir_sal( + ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1), + (mr_energy >> 15) - 25 + ); +#else + mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) / + sqrt(dot_product(fc_v, fc_v, subframe_size, 0)); + return mr_energy >> 12; +#endif +} diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_pitch_delay.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_pitch_delay.h @@ -0,0 +1,220 @@ +/* + * gain code, gain pitch and pitch delay decoding + * + * Copyright (c) 2008 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FFMPEG_ACELP_PITCH_DELAY_H +#define FFMPEG_ACELP_PITCH_DELAY_H + +#include <stdint.h> + +#define PITCH_DELAY_MIN 20 +#define PITCH_DELAY_MAX 143 + +/** + * \brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3 + * resolution. + * \param ac_index adaptive codebook index (8 bits) + * + * \return pitch delay in 1/3 units + * + * Pitch delay is coded: + * with 1/3 resolution, 19 < pitch_delay < 85 + * integers only, 85 <= pitch_delay <= 143 + */ +int ff_acelp_decode_8bit_to_1st_delay3(int ac_index); + +/** + * \brief Decode pitch delay of the second subframe encoded by 5 or 6 bits + * with 1/3 precision. + * \param ac_index adaptive codebook index (5 or 6 bits) + * \param pitch_delay_min lower bound (integer) of pitch delay interval + * for second subframe + * + * \return pitch delay in 1/3 units + * + * Pitch delay is coded: + * with 1/3 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5 + * + * \remark The routine is used in G.729 @8k, AMR @10.2k, AMR @7.95k, + * AMR @7.4k for the second subframe. + */ +int ff_acelp_decode_5_6_bit_to_2nd_delay3( + int ac_index, + int pitch_delay_min); + +/** + * \brief Decode pitch delay with 1/3 precision. + * \param ac_index adaptive codebook index (4 bits) + * \param pitch_delay_min lower bound (integer) of pitch delay interval for + * second subframe + * + * \return pitch delay in 1/3 units + * + * Pitch delay is coded: + * integers only, -6 < pitch_delay - int(prev_pitch_delay) <= -2 + * with 1/3 resolution, -2 < pitch_delay - int(prev_pitch_delay) < 1 + * integers only, 1 <= pitch_delay - int(prev_pitch_delay) < 5 + * + * \remark The routine is used in G.729 @6.4k, AMR @6.7k, AMR @5.9k, + * AMR @5.15k, AMR @4.75k for the second subframe. + */ +int ff_acelp_decode_4bit_to_2nd_delay3( + int ac_index, + int pitch_delay_min); + +/** + * \brief Decode pitch delay of the first subframe encoded by 9 bits + * with 1/6 precision. + * \param ac_index adaptive codebook index (9 bits) + * \param pitch_delay_min lower bound (integer) of pitch delay interval for + * second subframe + * + * \return pitch delay in 1/6 units + * + * Pitch delay is coded: + * with 1/6 resolution, 17 < pitch_delay < 95 + * integers only, 95 <= pitch_delay <= 143 + * + * \remark The routine is used in AMR @12.2k for the first and third subframes. + */ +int ff_acelp_decode_9bit_to_1st_delay6(int ac_index); + +/** + * \brief Decode pitch delay of the second subframe encoded by 6 bits + * with 1/6 precision. + * \param ac_index adaptive codebook index (6 bits) + * \param pitch_delay_min lower bound (integer) of pitch delay interval for + * second subframe + * + * \return pitch delay in 1/6 units + * + * Pitch delay is coded: + * with 1/6 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5 + * + * \remark The routine is used in AMR @12.2k for the second and fourth subframes. + */ +int ff_acelp_decode_6bit_to_2nd_delay6( + int ac_index, + int pitch_delay_min); + +/** + * \brief Update past quantized energies + * \param quant_energy [in/out] past quantized energies (5.10) + * \param gain_corr_factor gain correction factor + * \param log2_ma_pred_order log2() of MA prediction order + * \param erasure frame erasure flag + * + * If frame erasure flag is not equal to zero, memory is updated with + * averaged energy, attenuated by 4dB: + * max(avg(quant_energy[i])-4, -14), i=0,ma_pred_order + * + * In normal mode memory is updated with + * Er - Ep = 20 * log10(gain_corr_factor) + * + * \remark The routine is used in G.729 and AMR (all modes). + */ +void ff_acelp_update_past_gain( + int16_t* quant_energy, + int gain_corr_factor, + int log2_ma_pred_order, + int erasure); + +/** + * \brief Decode the adaptive codebook gain and add + * correction (4.1.5 and 3.9.1 of G.729). + * \param gain_corr_factor gain correction factor (2.13) + * \param fc_v fixed-codebook vector (2.13) + * \param mr_energy mean innovation energy and fixed-point correction (7.13) + * \param quant_energy [in/out] past quantized energies (5.10) + * \param subframe_size length of subframe + * \param ma_pred_order MA prediction order + * + * \return quantized fixed-codebook gain (14.1) + * + * The routine implements equations 69, 66 and 71 of the G.729 specification (3.9.1) + * + * Em - mean innovation energy (dB, constant, depends on decoding algorithm) + * Ep - mean-removed predicted energy (dB) + * Er - mean-removed innovation energy (dB) + * Ei - mean energy of the fixed-codebook contribution (dB) + * N - subframe_size + * M - MA (Moving Average) prediction order + * gc - fixed-codebook gain + * gc_p - predicted fixed-codebook gain + * + * Fixed codebook gain is computed using predicted gain gc_p and + * correction factor gain_corr_factor as shown below: + * + * gc = gc_p * gain_corr_factor + * + * The predicted fixed codebook gain gc_p is found by predicting + * the energy of the fixed-codebook contribution from the energy + * of previous fixed-codebook contributions. + * + * mean = 1/N * sum(i,0,N){ fc_v[i] * fc_v[i] } + * + * Ei = 10log(mean) + * + * Er = 10log(1/N * gc^2 * mean) - Em = 20log(gc) + Ei - Em + * + * Replacing Er with Ep and gc with gc_p we will receive: + * + * Ep = 10log(1/N * gc_p^2 * mean) - Em = 20log(gc_p) + Ei - Em + * + * and from above: + * + * gc_p = 10^((Ep - Ei + Em) / 20) + * + * Ep is predicted using past energies and prediction coefficients: + * + * Ep = sum(i,0,M){ ma_prediction_coeff[i] * quant_energy[i] } + * + * gc_p in fixed-point arithmetic is calculated as following: + * + * mean = 1/N * sum(i,0,N){ (fc_v[i] / 2^13) * (fc_v[i] / 2^13) } = + * = 1/N * sum(i,0,N) { fc_v[i] * fc_v[i] } / 2^26 + * + * Ei = 10log(mean) = -10log(N) - 10log(2^26) + + * + 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) + * + * Ep - Ei + Em = Ep + Em + 10log(N) + 10log(2^26) - + * - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) = + * = Ep + mr_energy - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) + * + * gc_p = 10 ^ ((Ep - Ei + Em) / 20) = + * = 2 ^ (3.3219 * (Ep - Ei + Em) / 20) = 2 ^ (0.166 * (Ep - Ei + Em)) + * + * where + * + * mr_energy = Em + 10log(N) + 10log(2^26) + * + * \remark The routine is used in G.729 and AMR (all modes). + */ +int16_t ff_acelp_decode_gain_code( + int gain_corr_factor, + const int16_t* fc_v, + int mr_energy, + const int16_t* quant_energy, + const int16_t* ma_prediction_coeff, + int subframe_size, + int max_pred_order); + +#endif /* FFMPEG_ACELP_PITCH_DELAY_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_vectors.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/acelp_vectors.h @@ -66,7 +66,7 @@ extern const uint8_t ff_fc_4pulses_8bits_track_4[32]; * \note (EE) Reference G.729D code also uses gray decoding for each * pulse index before looking up the value in the table. * - * Used in G.729 @6.4k (with gray coding), AMD @5.9k (without gray coding) + * Used in G.729 @6.4k (with gray coding), AMR @5.9k (without gray coding) */ extern const uint8_t ff_fc_2pulses_9bits_track1[16]; extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16]; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/adpcm.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/adpcm.c @@ -85,12 +85,12 @@ static const int AdaptationTable[] = { 768, 614, 512, 409, 307, 230, 230, 230 }; -static const int AdaptCoeff1[] = { - 256, 512, 0, 192, 240, 460, 392 +static const uint8_t AdaptCoeff1[] = { + 64, 128, 0, 48, 60, 115, 98 }; -static const int AdaptCoeff2[] = { - 0, -256, 0, 64, 0, -208, -232 +static const int8_t AdaptCoeff2[] = { + 0, -64, 0, 16, 0, -52, -58 }; /* These are for CD-ROM XA ADPCM */ @@ -226,7 +226,7 @@ static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, shor { int predictor, nibble, bias; - predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; + predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64; nibble= sample - predictor; if(nibble>=0) bias= c->idelta/2; @@ -330,7 +330,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, const int step = nodes[j]->step; int nidx; if(version == CODEC_ID_ADPCM_MS) { - const int predictor = ((nodes[j]->sample1 * c->coeff1) + (nodes[j]->sample2 * c->coeff2)) / 256; + const int predictor = ((nodes[j]->sample1 * c->coeff1) + (nodes[j]->sample2 * c->coeff2)) / 64; const int div = (sample - predictor) / step; const int nmin = av_clip(div-range, -8, 6); const int nmax = av_clip(div+range, -7, 7); @@ -563,7 +563,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, //Init the encoder state for(i=0; i<avctx->channels; i++){ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits - put_bits(&pb, 16, samples[i] & 0xFFFF); + put_sbits(&pb, 16, samples[i]); put_bits(&pb, 6, c->status[i].step_index); c->status[i].prev_sample = (signed short)samples[i]; } @@ -604,15 +604,15 @@ static int adpcm_encode_frame(AVCodecContext *avctx, bytestream_put_le16(&dst, c->status[i].idelta); } for(i=0; i<avctx->channels; i++){ + c->status[i].sample2= *samples++; + } + for(i=0; i<avctx->channels; i++){ c->status[i].sample1= *samples++; bytestream_put_le16(&dst, c->status[i].sample1); } - for(i=0; i<avctx->channels; i++){ - c->status[i].sample2= *samples++; - + for(i=0; i<avctx->channels; i++) bytestream_put_le16(&dst, c->status[i].sample2); - } if(avctx->trellis > 0) { int n = avctx->block_align - 7*avctx->channels; @@ -732,7 +732,7 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) { int predictor; - predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; + predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64; predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; c->sample2 = c->sample1; @@ -972,8 +972,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, for(i=0; i<avctx->channels; i++){ cs = &(c->status[i]); - cs->predictor = *samples++ = (int16_t)(src[0] + (src[1]<<8)); - src+=2; + cs->predictor = *samples++ = (int16_t)bytestream_get_le16(&src); cs->step_index = *src++; if (cs->step_index > 88){ @@ -996,13 +995,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx, break; case CODEC_ID_ADPCM_4XM: cs = &(c->status[0]); - c->status[0].predictor= (int16_t)(src[0] + (src[1]<<8)); src+=2; + c->status[0].predictor= (int16_t)bytestream_get_le16(&src); if(st){ - c->status[1].predictor= (int16_t)(src[0] + (src[1]<<8)); src+=2; + c->status[1].predictor= (int16_t)bytestream_get_le16(&src); } - c->status[0].step_index= (int16_t)(src[0] + (src[1]<<8)); src+=2; + c->status[0].step_index= (int16_t)bytestream_get_le16(&src); if(st){ - c->status[1].step_index= (int16_t)(src[0] + (src[1]<<8)); src+=2; + c->status[1].step_index= (int16_t)bytestream_get_le16(&src); } if (cs->step_index < 0) cs->step_index = 0; if (cs->step_index > 88) cs->step_index = 88; @@ -1026,34 +1025,28 @@ static int adpcm_decode_frame(AVCodecContext *avctx, n = buf_size - 7 * avctx->channels; if (n < 0) return -1; - block_predictor[0] = av_clip(*src++, 0, 7); + block_predictor[0] = av_clip(*src++, 0, 6); block_predictor[1] = 0; if (st) - block_predictor[1] = av_clip(*src++, 0, 7); - c->status[0].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); - src+=2; + block_predictor[1] = av_clip(*src++, 0, 6); + c->status[0].idelta = (int16_t)bytestream_get_le16(&src); if (st){ - c->status[1].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); - src+=2; + c->status[1].idelta = (int16_t)bytestream_get_le16(&src); } c->status[0].coeff1 = AdaptCoeff1[block_predictor[0]]; c->status[0].coeff2 = AdaptCoeff2[block_predictor[0]]; c->status[1].coeff1 = AdaptCoeff1[block_predictor[1]]; c->status[1].coeff2 = AdaptCoeff2[block_predictor[1]]; - c->status[0].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); - src+=2; - if (st) c->status[1].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); - if (st) src+=2; - c->status[0].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); - src+=2; - if (st) c->status[1].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); - if (st) src+=2; + c->status[0].sample1 = bytestream_get_le16(&src); + if (st) c->status[1].sample1 = bytestream_get_le16(&src); + c->status[0].sample2 = bytestream_get_le16(&src); + if (st) c->status[1].sample2 = bytestream_get_le16(&src); - *samples++ = c->status[0].sample1; - if (st) *samples++ = c->status[1].sample1; *samples++ = c->status[0].sample2; if (st) *samples++ = c->status[1].sample2; + *samples++ = c->status[0].sample1; + if (st) *samples++ = c->status[1].sample1; for(;n>0;n--) { *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], src[0] >> 4 ); *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F); @@ -1064,14 +1057,14 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; - c->status[0].predictor = (int16_t)(src[0] | (src[1] << 8)); - c->status[0].step_index = src[2]; - src += 4; + c->status[0].predictor = (int16_t)bytestream_get_le16(&src); + c->status[0].step_index = *src++; + src++; *samples++ = c->status[0].predictor; if (st) { - c->status[1].predictor = (int16_t)(src[0] | (src[1] << 8)); - c->status[1].step_index = src[2]; - src += 4; + c->status[1].predictor = (int16_t)bytestream_get_le16(&src); + c->status[1].step_index = *src++; + src++; *samples++ = c->status[1].predictor; } while (src < buf + buf_size) { @@ -1099,8 +1092,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if(buf_size + 16 > (samples_end - samples)*3/8) return -1; - c->status[0].predictor = (int16_t)(src[10] | (src[11] << 8)); - c->status[1].predictor = (int16_t)(src[12] | (src[13] << 8)); + c->status[0].predictor = (int16_t)AV_RL16(src + 10); + c->status[1].predictor = (int16_t)AV_RL16(src + 12); c->status[0].step_index = src[14]; c->status[1].step_index = src[15]; /* sign extend the predictors */ @@ -1196,14 +1189,10 @@ static int adpcm_decode_frame(AVCodecContext *avctx, break; } src += 4; - current_left_sample = (int16_t)AV_RL16(src); - src += 2; - previous_left_sample = (int16_t)AV_RL16(src); - src += 2; - current_right_sample = (int16_t)AV_RL16(src); - src += 2; - previous_right_sample = (int16_t)AV_RL16(src); - src += 2; + current_left_sample = (int16_t)bytestream_get_le16(&src); + previous_left_sample = (int16_t)bytestream_get_le16(&src); + current_right_sample = (int16_t)bytestream_get_le16(&src); + previous_right_sample = (int16_t)bytestream_get_le16(&src); for (count1 = 0; count1 < samples_in_chunk/28;count1++) { coeff1l = ea_adpcm_table[ *src >> 4 ]; @@ -1636,6 +1625,7 @@ AVCodec name ## _decoder = { \ #define ADPCM_CODEC(id,name,long_name_) \ ADPCM_ENCODER(id,name,long_name_) ADPCM_DECODER(id,name,long_name_) +/* Note: Do not forget to add new entries to the Makefile as well. */ ADPCM_DECODER(CODEC_ID_ADPCM_4XM, adpcm_4xm, "4X Movie ADPCM"); ADPCM_DECODER(CODEC_ID_ADPCM_CT, adpcm_ct, "Creative Technology ADPCM"); ADPCM_DECODER(CODEC_ID_ADPCM_EA, adpcm_ea, "Electronic Arts ADPCM"); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/allcodecs.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/allcodecs.c @@ -78,6 +78,7 @@ void avcodec_register_all(void) REGISTER_DECODER (DSICINVIDEO, dsicinvideo); REGISTER_ENCDEC (DVVIDEO, dvvideo); REGISTER_DECODER (DXA, dxa); + REGISTER_DECODER (EACMV, eacmv); REGISTER_DECODER (EIGHTBPS, eightbps); REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp); REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib); @@ -109,6 +110,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (MJPEG, mjpeg); REGISTER_DECODER (MJPEGB, mjpegb); REGISTER_DECODER (MMVIDEO, mmvideo); + REGISTER_DECODER (MOTIONPIXELS, motionpixels); REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc); REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); @@ -189,6 +191,7 @@ void avcodec_register_all(void) REGISTER_DECODER (IMC, imc); REGISTER_DECODER (MACE3, mace3); REGISTER_DECODER (MACE6, mace6); + REGISTER_DECODER (MLP, mlp); REGISTER_ENCDEC (MP2, mp2); REGISTER_DECODER (MP3, mp3); REGISTER_DECODER (MP3ADU, mp3adu); @@ -310,6 +313,7 @@ void avcodec_register_all(void) REGISTER_PARSER (MPEGVIDEO, mpegvideo); REGISTER_PARSER (PNM, pnm); REGISTER_PARSER (VC1, vc1); + REGISTER_PARSER (VP3, vp3); /* bitstream filters */ REGISTER_BSF (DUMP_EXTRADATA, dump_extradata); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/apedec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/apedec.c @@ -161,29 +161,6 @@ typedef struct APEContext { } APEContext; // TODO: dsputilize -static inline void vector_add(int16_t * v1, int16_t * v2, int order) -{ - while (order--) - *v1++ += *v2++; -} - -// TODO: dsputilize -static inline void vector_sub(int16_t * v1, int16_t * v2, int order) -{ - while (order--) - *v1++ -= *v2++; -} - -// TODO: dsputilize -static inline int32_t scalarproduct(int16_t * v1, int16_t * v2, int order) -{ - int res = 0; - - while (order--) - res += *v1++ * *v2++; - - return res; -} static av_cold int ape_decode_init(AVCodecContext * avctx) { @@ -672,19 +649,19 @@ static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order); } -static inline void do_apply_filter(int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) +static inline void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) { int res; int absres; while (count--) { /* round fixedpoint scalar product */ - res = (scalarproduct(f->delay - order, f->coeffs, order) + (1 << (fracbits - 1))) >> fracbits; + res = (ctx->dsp.scalarproduct_int16(f->delay - order, f->coeffs, order, 0) + (1 << (fracbits - 1))) >> fracbits; if (*data < 0) - vector_add(f->coeffs, f->adaptcoeffs - order, order); + ctx->dsp.add_int16(f->coeffs, f->adaptcoeffs - order, order); else if (*data > 0) - vector_sub(f->coeffs, f->adaptcoeffs - order, order); + ctx->dsp.sub_int16(f->coeffs, f->adaptcoeffs - order, order); res += *data; @@ -736,9 +713,9 @@ static void apply_filter(APEContext * ctx, APEFilter *f, int32_t * data0, int32_t * data1, int count, int order, int fracbits) { - do_apply_filter(ctx->fileversion, &f[0], data0, count, order, fracbits); + do_apply_filter(ctx, ctx->fileversion, &f[0], data0, count, order, fracbits); if (data1) - do_apply_filter(ctx->fileversion, &f[1], data1, count, order, fracbits); + do_apply_filter(ctx, ctx->fileversion, &f[1], data1, count, order, fracbits); } static void ape_apply_filters(APEContext * ctx, int32_t * decoded0, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/armv4l/dsputil_arm.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/armv4l/dsputil_arm.c @@ -203,6 +203,11 @@ static void simple_idct_ipp_add(uint8_t *dest, int line_size, DCTELEM *block) } #endif +int mm_support(void) +{ + return ENABLE_IWMMXT * MM_IWMMXT; +} + void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx) { int idct_algo= avctx->idct_algo; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/armv4l/mathops.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/armv4l/mathops.h @@ -33,10 +33,39 @@ hi; }) #endif +#ifdef HAVE_ARMV6 +static inline av_const int MULH(int a, int b) +{ + int r; + asm ("smmul %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} +#define MULH MULH +#else #define MULH(a, b) \ ({ int lo, hi;\ asm ("smull %0, %1, %2, %3" : "=&r"(lo), "=&r"(hi) : "r"(b), "r"(a));\ hi; }) +#endif + +static inline av_const int64_t MUL64(int a, int b) +{ + union { uint64_t x; unsigned hl[2]; } x; + asm ("smull %0, %1, %2, %3" + : "=r"(x.hl[0]), "=r"(x.hl[1]) : "r"(a), "r"(b)); + return x.x; +} +#define MUL64 MUL64 + +static inline av_const int64_t MAC64(int64_t d, int a, int b) +{ + union { uint64_t x; unsigned hl[2]; } x = { d }; + asm ("smlal %0, %1, %2, %3" + : "+r"(x.hl[0]), "+r"(x.hl[1]) : "r"(a), "r"(b)); + return x.x; +} +#define MAC64(d, a, b) ((d) = MAC64(d, a, b)) +#define MLS64(d, a, b) MAC64(d, -(a), b) #if defined(HAVE_ARMV5TE) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/asv1.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/asv1.c @@ -166,7 +166,7 @@ static inline void asv1_put_level(PutBitContext *pb, int level){ if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]); else{ put_bits(pb, level_tab[3][1], level_tab[3][0]); - put_bits(pb, 8, level&0xFF); + put_sbits(pb, 8, level); } } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/atrac3data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/atrac3data.h @@ -97,11 +97,11 @@ static const uint8_t huff_tab_sizes[7] = { 9, 5, 7, 9, 15, 31, 63, }; -static const uint8_t* huff_codes[7] = { +static const uint8_t* const huff_codes[7] = { huffcode1,huffcode2,huffcode3,huffcode4,huffcode5,huffcode6,huffcode7, }; -static const uint8_t* huff_bits[7] = { +static const uint8_t* const huff_bits[7] = { huffbits1,huffbits2,huffbits3,huffbits4,huffbits5,huffbits6,huffbits7, }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/avcodec.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/avcodec.h @@ -30,8 +30,8 @@ #include "libavutil/avutil.h" #define LIBAVCODEC_VERSION_MAJOR 51 -#define LIBAVCODEC_VERSION_MINOR 57 -#define LIBAVCODEC_VERSION_MICRO 2 +#define LIBAVCODEC_VERSION_MINOR 60 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -186,6 +186,8 @@ enum CodecID { CODEC_ID_ESCAPE124, CODEC_ID_DIRAC, CODEC_ID_BFI, + CODEC_ID_CMV, + CODEC_ID_MOTIONPIXELS, /* various PCM "codecs" */ CODEC_ID_PCM_S16LE= 0x10000, @@ -311,6 +313,8 @@ enum CodecID { /* other specific kind of codecs (generally used for attachments) */ CODEC_ID_TTF= 0x18000, + CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS * stream (only used by libavformat) */ }; @@ -1113,7 +1117,14 @@ typedef struct AVCodecContext { /** * strictly follow the standard (MPEG4, ...). * - encoding: Set by user. - * - decoding: unused + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things. While setting it to inofficial or lower + * will mean the encoder might use things that are not supported by all + * spec compliant decoders. Decoders make no difference between normal, + * inofficial and experimental, that is they always try to decode things + * when they can unless they are explicitly asked to behave stupid + * (=strictly conform to the specs) */ int strict_std_compliance; #define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software. @@ -2514,8 +2525,10 @@ AVCodec *av_codec_next(AVCodec *c); /* returns LIBAVCODEC_VERSION_INT constant */ unsigned avcodec_version(void); +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) /* returns LIBAVCODEC_BUILD constant */ -unsigned avcodec_build(void); +attribute_deprecated unsigned avcodec_build(void); +#endif /** * Initializes libavcodec. diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/bitstream.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/bitstream.c @@ -30,6 +30,13 @@ #include "avcodec.h" #include "bitstream.h" +const uint8_t ff_log2_run[32]={ + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9,10,11,12,13,14,15 +}; + /** * Same as av_mallocz_static(), but does a realloc. * diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/bitstream.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/bitstream.h @@ -49,7 +49,6 @@ //#define A32_BITSTREAM_READER # endif #endif -#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO extern const uint8_t ff_reverse[256]; @@ -177,38 +176,6 @@ typedef struct RL_VLC_ELEM { #define UNALIGNED_STORES_ARE_BAD #endif -/* used to avoid misaligned exceptions on some archs (alpha, ...) */ -#if defined(ARCH_X86) -# define unaligned16(a) (*(const uint16_t*)(a)) -# define unaligned32(a) (*(const uint32_t*)(a)) -# define unaligned64(a) (*(const uint64_t*)(a)) -#else -# ifdef __GNUC__ -# define unaligned(x) \ -static inline uint##x##_t unaligned##x(const void *v) { \ - struct Unaligned { \ - uint##x##_t i; \ - } __attribute__((packed)); \ - \ - return ((const struct Unaligned *) v)->i; \ -} -# elif defined(__DECC) -# define unaligned(x) \ -static inline uint##x##_t unaligned##x(const void *v) { \ - return *(const __unaligned uint##x##_t *) v; \ -} -# else -# define unaligned(x) \ -static inline uint##x##_t unaligned##x(const void *v) { \ - return *(const uint##x##_t *) v; \ -} -# endif -unaligned(16) -unaligned(32) -unaligned(64) -#undef unaligned -#endif /* defined(ARCH_X86) */ - #ifndef ALT_BITSTREAM_WRITER static inline void put_bits(PutBitContext *s, int n, unsigned int value) { @@ -316,6 +283,13 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) } #endif +static inline void put_sbits(PutBitContext *pb, int bits, int32_t val) +{ + assert(bits >= 0 && bits <= 31); + + put_bits(pb, bits, val & ((1<<bits)-1)); +} + static inline uint8_t* pbBufPtr(PutBitContext *s) { @@ -484,26 +458,13 @@ static inline void skip_bits_long(GetBitContext *s, int n){ (gb)->cache= name##_cache;\ (gb)->buffer_ptr= name##_buffer_ptr;\ -#ifdef LIBMPEG2_BITSTREAM_READER_HACK - # define UPDATE_CACHE(name, gb)\ if(name##_bit_count >= 0){\ - name##_cache+= (int)be2me_16(*(uint16_t*)name##_buffer_ptr) << name##_bit_count;\ - name##_buffer_ptr += 2;\ - name##_bit_count-= 16;\ - }\ - -#else - -# define UPDATE_CACHE(name, gb)\ - if(name##_bit_count >= 0){\ - name##_cache+= ((name##_buffer_ptr[0]<<8) + name##_buffer_ptr[1]) << name##_bit_count;\ + name##_cache+= AV_RB16(name##_buffer_ptr) << name##_bit_count; \ name##_buffer_ptr+=2;\ name##_bit_count-= 16;\ }\ -#endif - # define SKIP_CACHE(name, gb, num)\ name##_cache <<= (num);\ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/cook.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/cook.c @@ -232,16 +232,15 @@ static int init_cook_vlc_tables(COOKContext *q) { static int init_cook_mlt(COOKContext *q) { int j; - float alpha; int mlt_size = q->samples_per_channel; if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0) return -1; /* Initialize the MLT window: simple sine window. */ - alpha = M_PI / (2.0 * (float)mlt_size); + ff_sine_window_init(q->mlt_window, mlt_size); for(j=0 ; j<mlt_size ; j++) - q->mlt_window[j] = sin((j + 0.5) * alpha) * sqrt(2.0 / q->samples_per_channel); + q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); /* Initialize the MDCT. */ if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1)) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/cookdata.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/cookdata.h @@ -422,12 +422,12 @@ static const uint16_t cvh_huffcodes6[32] = { 0x003c,0x01fc,0x00fb,0x03fd,0x00fc,0x03fe,0x01fd,0x07ff, }; -static const uint16_t* cvh_huffcodes[7] = { +static const uint16_t* const cvh_huffcodes[7] = { cvh_huffcodes0, cvh_huffcodes1, cvh_huffcodes2, cvh_huffcodes3, cvh_huffcodes4, cvh_huffcodes5, cvh_huffcodes6, }; -static const uint8_t* cvh_huffbits[7] = { +static const uint8_t* const cvh_huffbits[7] = { cvh_huffbits0, cvh_huffbits1, cvh_huffbits2, cvh_huffbits3, cvh_huffbits4, cvh_huffbits5, cvh_huffbits6, }; @@ -488,12 +488,12 @@ static const uint8_t ccpl_huffbits6[63] = { 14,14,16, }; -static const uint16_t* ccpl_huffcodes[5] = { +static const uint16_t* const ccpl_huffcodes[5] = { ccpl_huffcodes2,ccpl_huffcodes3, ccpl_huffcodes4,ccpl_huffcodes5,ccpl_huffcodes6 }; -static const uint8_t* ccpl_huffbits[5] = { +static const uint8_t* const ccpl_huffbits[5] = { ccpl_huffbits2,ccpl_huffbits3, ccpl_huffbits4,ccpl_huffbits5,ccpl_huffbits6 }; @@ -556,7 +556,7 @@ static const float cplscale6[63] = { 0.142307326197624,0.109772264957428,0.0631198287010193, }; -static const float* cplscales[5] = { +static const float* const cplscales[5] = { cplscale2, cplscale3, cplscale4, cplscale5, cplscale6, }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dcahuff.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dcahuff.h @@ -1037,7 +1037,7 @@ static const uint8_t bitalloc_maxbits[10][7] = { { 9, 9, 9, 9, 9, 9, 9 } }; -static const uint16_t* bitalloc_codes[10][8] = { +static const uint16_t* const bitalloc_codes[10][8] = { { bitalloc_3_codes, NULL }, { bitalloc_5_codes_a, bitalloc_5_codes_b, bitalloc_5_codes_c, NULL }, { bitalloc_7_codes_a, bitalloc_7_codes_b, bitalloc_7_codes_c, NULL }, @@ -1055,7 +1055,7 @@ static const uint16_t* bitalloc_codes[10][8] = { bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL } }; -static const uint8_t* bitalloc_bits[10][8] = { +static const uint8_t* const bitalloc_bits[10][8] = { { bitalloc_3_bits, NULL }, { bitalloc_5_bits_a, bitalloc_5_bits_b, bitalloc_5_bits_c, NULL }, { bitalloc_7_bits_a, bitalloc_7_bits_b, bitalloc_7_bits_c, NULL }, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dct-test.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dct-test.c @@ -32,17 +32,13 @@ #include <unistd.h> #include <math.h> -#include "dsputil.h" +#include "libavutil/common.h" #include "simple_idct.h" #include "faandct.h" #include "faanidct.h" #include "i386/idct_xvid.h" -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - #undef printf #undef random @@ -68,7 +64,7 @@ extern void fdct_altivec (DCTELEM *block); struct algo { - char *name; + const char *name; enum { FDCT, IDCT } is_idct; void (* func) (DCTELEM *block); void (* ref) (DCTELEM *block); @@ -82,6 +78,8 @@ struct algo { #define FAAN_SCALE NO_PERM #endif +static int cpu_flags; + struct algo algos[] = { {"REF-DBL", 0, fdct, fdct, NO_PERM}, {"FAAN", 0, ff_faandct, fdct, FAAN_SCALE}, @@ -175,6 +173,14 @@ static DCTELEM block[64] __attribute__ ((aligned (16))); static DCTELEM block1[64] __attribute__ ((aligned (8))); static DCTELEM block_org[64] __attribute__ ((aligned (8))); +static inline void mmx_emms(void) +{ +#ifdef HAVE_MMX + if (cpu_flags & MM_MMX) + asm volatile ("emms\n\t"); +#endif +} + void dct_error(const char *name, int is_idct, void (*fdct_func)(DCTELEM *block), void (*fdct_ref)(DCTELEM *block), int form, int test) @@ -252,7 +258,7 @@ void dct_error(const char *name, int is_idct, #endif fdct_func(block); - emms_c(); /* for ff_mmx_idct */ + mmx_emms(); if (form == SCALE_PERM) { for(i=0; i<64; i++) { @@ -288,7 +294,7 @@ void dct_error(const char *name, int is_idct, } #endif } - for(i=0; i<64; i++) sysErrMax= MAX(sysErrMax, FFABS(sysErr[i])); + for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i])); #if 1 // dump systematic errors for(i=0; i<64; i++){ @@ -349,7 +355,7 @@ void dct_error(const char *name, int is_idct, it1 += NB_ITS_SPEED; ti1 = gettime() - ti; } while (ti1 < 1000000); - emms_c(); + mmx_emms(); printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", @@ -509,7 +515,7 @@ void idct248_error(const char *name, it1 += NB_ITS_SPEED; ti1 = gettime() - ti; } while (ti1 < 1000000); - emms_c(); + mmx_emms(); printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", @@ -531,10 +537,10 @@ int main(int argc, char **argv) int test_idct = 0, test_248_dct = 0; int c,i; int test=1; + cpu_flags = mm_support(); init_fdct(); idct_mmx_init(); - mm_flags = mm_support(); for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; for(i=0;i<MAX_NEG_CROP;i++) { @@ -568,7 +574,7 @@ int main(int argc, char **argv) idct248_error("SIMPLE-C", ff_simple_idct248_put); } else { for (i=0;algos[i].name;i++) - if (algos[i].is_idct == test_idct && !(~mm_flags & algos[i].mm_support)) { + if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) { dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test); } } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dpcm.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dpcm.c @@ -48,7 +48,7 @@ typedef struct DPCMContext { #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; -static int interplay_delta_table[] = { +static const int interplay_delta_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dsputil.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dsputil.c @@ -3930,20 +3930,74 @@ void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, dst[i*step] = src0[i] * src1[i] + src2[i] + src3; } -void ff_float_to_int16_c(int16_t *dst, const float *src, int len){ +void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len){ + int i,j; + dst += len; + win += len; + src0+= len; + for(i=-len, j=len-1; i<0; i++, j--) { + float s0 = src0[i]; + float s1 = src1[j]; + float wi = win[i]; + float wj = win[j]; + dst[i] = s0*wj - s1*wi + add_bias; + dst[j] = s0*wi + s1*wj + add_bias; + } +} + +static av_always_inline int float_to_int16_one(const float *src){ + int_fast32_t tmp = *(const int32_t*)src; + if(tmp & 0xf0000){ + tmp = (0x43c0ffff - tmp)>>31; + // is this faster on some gcc/cpu combinations? +// if(tmp > 0x43c0ffff) tmp = 0xFFFF; +// else tmp = 0; + } + return tmp - 0x8000; +} + +void ff_float_to_int16_c(int16_t *dst, const float *src, long len){ int i; - for(i=0; i<len; i++) { - int_fast32_t tmp = ((const int32_t*)src)[i]; - if(tmp & 0xf0000){ - tmp = (0x43c0ffff - tmp)>>31; - // is this faster on some gcc/cpu combinations? -// if(tmp > 0x43c0ffff) tmp = 0xFFFF; -// else tmp = 0; + for(i=0; i<len; i++) + dst[i] = float_to_int16_one(src+i); +} + +void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels){ + int i,j,c; + if(channels==2){ + for(i=0; i<len; i++){ + dst[2*i] = float_to_int16_one(src[0]+i); + dst[2*i+1] = float_to_int16_one(src[1]+i); } - dst[i] = tmp - 0x8000; + }else{ + for(c=0; c<channels; c++) + for(i=0, j=c; i<len; i++, j+=channels) + dst[j] = float_to_int16_one(src[c]+i); } } +static void add_int16_c(int16_t * v1, int16_t * v2, int order) +{ + while (order--) + *v1++ += *v2++; +} + +static void sub_int16_c(int16_t * v1, int16_t * v2, int order) +{ + while (order--) + *v1++ -= *v2++; +} + +static int32_t scalarproduct_int16_c(int16_t * v1, int16_t * v2, int order, int shift) +{ + int res = 0; + + while (order--) + res += (*v1++ * *v2++) >> shift; + + return res; +} + #define W0 2048 #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ @@ -4428,7 +4482,12 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->vector_fmul = vector_fmul_c; c->vector_fmul_reverse = vector_fmul_reverse_c; c->vector_fmul_add_add = ff_vector_fmul_add_add_c; + c->vector_fmul_window = ff_vector_fmul_window_c; c->float_to_int16 = ff_float_to_int16_c; + c->float_to_int16_interleave = ff_float_to_int16_interleave_c; + c->add_int16 = add_int16_c; + c->sub_int16 = sub_int16_c; + c->scalarproduct_int16 = scalarproduct_int16_c; c->shrink[0]= ff_img_copy_plane; c->shrink[1]= ff_shrink22; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dsputil.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dsputil.h @@ -63,7 +63,9 @@ void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, const float *src2, int src3, int blocksize, int step); -void ff_float_to_int16_c(int16_t *dst, const float *src, int len); +void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, + const float *win, float add_bias, int len); +void ff_float_to_int16_c(int16_t *dst, const float *src, long len); /* encoding scans */ extern const uint8_t ff_alternate_horizontal_scan[64]; @@ -345,7 +347,7 @@ typedef struct DSPContext { void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta); // h264_loop_filter_strength: simd only. the C version is inlined in h264.c void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], - int bidir, int edges, int step, int mask_mv0, int mask_mv1); + int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field); void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); @@ -364,10 +366,13 @@ typedef struct DSPContext { void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ void (*vector_fmul_add_add)(float *dst, const float *src0, const float *src1, const float *src2, int src3, int len, int step); + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ + void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ - void (*float_to_int16)(int16_t *dst, const float *src, int len); + void (*float_to_int16)(int16_t *dst, const float *src, long len); + void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); @@ -451,6 +456,23 @@ typedef struct DSPContext { void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, int * range, int * sum, int edges); + /* ape functions */ + /** + * Add contents of the second vector to the first one. + * @param len length of vectors, should be multiple of 16 + */ + void (*add_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); + /** + * Add contents of the second vector to the first one. + * @param len length of vectors, should be multiple of 16 + */ + void (*sub_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); + /** + * Calculate scalar product of two vectors. + * @param len length of vectors, should be multiple of 16 + * @param shift number of bits to discard from product + */ + int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift); } DSPContext; void dsputil_static_init(void); @@ -578,6 +600,11 @@ extern int mm_flags; #define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) #define STRIDE_ALIGN 16 +#else + +#define mm_flags 0 +#define mm_support() 0 + #endif #ifndef DECLARE_ALIGNED_8 @@ -614,6 +641,8 @@ typedef struct FFTContext { void (*fft_calc)(struct FFTContext *s, FFTComplex *z); void (*imdct_calc)(struct MDCTContext *s, FFTSample *output, const FFTSample *input, FFTSample *tmp); + void (*imdct_half)(struct MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp); } FFTContext; int ff_fft_init(FFTContext *s, int nbits, int inverse); @@ -649,13 +678,26 @@ typedef struct MDCTContext { */ void ff_kbd_window_init(float *window, float alpha, int n); +/** + * Generate a sine window. + * @param window pointer to half window + * @param n size of half window + */ +void ff_sine_window_init(float *window, int n); + int ff_mdct_init(MDCTContext *s, int nbits, int inverse); void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input, FFTSample *tmp); +void ff_imdct_half(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp); void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input, FFTSample *tmp); +void ff_imdct_half_3dn2(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp); void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, const FFTSample *input, FFTSample *tmp); +void ff_imdct_half_sse(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp); void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input, FFTSample *tmp); void ff_mdct_end(MDCTContext *s); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dv.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dv.c @@ -1000,7 +1000,7 @@ static int dv_decode_mt(AVCodecContext *avctx, void* sl) return 0; } -#ifdef CONFIG_ENCODERS +#ifdef CONFIG_DVVIDEO_ENCODER static int dv_encode_mt(AVCodecContext *avctx, void* sl) { DVVideoContext *s = avctx->priv_data; @@ -1137,6 +1137,7 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, ui return 5; } +#ifdef CONFIG_DVVIDEO_ENCODER static void dv_format_frame(DVVideoContext* c, uint8_t* buf) { int chan, i, j, k; @@ -1187,7 +1188,6 @@ static void dv_format_frame(DVVideoContext* c, uint8_t* buf) } -#ifdef CONFIG_ENCODERS static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, void *data) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dvdsubdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/dvdsubdec.c @@ -440,6 +440,8 @@ static int find_smallest_bounding_rectangle(AVSubtitle *s) #ifdef DEBUG #undef fprintf +#undef perror +#undef exit static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, uint32_t *rgba_palette) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/eacmv.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/eacmv.c @@ -0,0 +1,214 @@ +/* + * Electronic Arts CMV Video Decoder + * Copyright (c) 2007-2008 Peter Ross + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file eacmv.c + * Electronic Arts CMV Video Decoder + * by Peter Ross (suxen_drol at hotmail dot com) + * + * Technical details here: + * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_CMV + */ + +#include "avcodec.h" + +typedef struct CmvContext { + AVCodecContext *avctx; + AVFrame frame; ///< current + AVFrame last_frame; ///< last + AVFrame last2_frame; ///< second-last + int width, height; + unsigned int palette[AVPALETTE_COUNT]; +} CmvContext; + +static av_cold int cmv_decode_init(AVCodecContext *avctx){ + CmvContext *s = avctx->priv_data; + s->avctx = avctx; + avctx->pix_fmt = PIX_FMT_PAL8; + return 0; +} + +static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){ + unsigned char *dst = s->frame.data[0]; + int i; + + for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) { + memcpy(dst, buf, s->avctx->width); + dst += s->frame.linesize[0]; + buf += s->avctx->width; + } +} + +static void cmv_motcomp(unsigned char *dst, int dst_stride, + const unsigned char *src, int src_stride, + int x, int y, + int xoffset, int yoffset, + int width, int height){ + int i,j; + + for(j=y;j<y+4;j++) + for(i=x;i<x+4;i++) + { + if (i+xoffset>=0 && i+xoffset<width && + j+yoffset>=0 && j+yoffset<height) { + dst[j*dst_stride + i] = src[(j+yoffset)*src_stride + i+xoffset]; + }else{ + dst[j*dst_stride + i] = 0; + } + } +} + +static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){ + const uint8_t *raw = buf + (s->avctx->width*s->avctx->height/16); + int x,y,i; + + i = 0; + for(y=0; y<s->avctx->height/4; y++) + for(x=0; x<s->avctx->width/4 && buf+i<buf_end; x++) { + if (buf[i]==0xFF) { + unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4; + if (raw+16<buf_end && *raw==0xFF) { /* intra */ + raw++; + memcpy(dst, raw, 4); + memcpy(dst+s->frame.linesize[0], raw+4, 4); + memcpy(dst+2*s->frame.linesize[0], raw+8, 4); + memcpy(dst+3*s->frame.linesize[0], raw+12, 4); + raw+=16; + }else if(raw<buf_end) { /* inter using second-last frame as reference */ + int xoffset = (*raw & 0xF) - 7; + int yoffset = ((*raw >> 4)) - 7; + cmv_motcomp(s->frame.data[0], s->frame.linesize[0], + s->last2_frame.data[0], s->last2_frame.linesize[0], + x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); + raw++; + } + }else{ /* inter using last frame as reference */ + int xoffset = (buf[i] & 0xF) - 7; + int yoffset = ((buf[i] >> 4)) - 7; + cmv_motcomp(s->frame.data[0], s->frame.linesize[0], + s->last_frame.data[0], s->last_frame.linesize[0], + x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); + } + i++; + } +} + +static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end) +{ + int pal_start, pal_count, i; + + if(buf+16>=buf_end) { + av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); + return; + } + + s->width = AV_RL16(&buf[4]); + s->height = AV_RL16(&buf[6]); + if (s->avctx->width!=s->width || s->avctx->height!=s->height) + avcodec_set_dimensions(s->avctx, s->width, s->height); + + s->avctx->time_base.num = 1; + s->avctx->time_base.den = AV_RL16(&buf[10]); + + pal_start = AV_RL16(&buf[12]); + pal_count = AV_RL16(&buf[14]); + + buf += 16; + for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf+2<buf_end; i++) { + s->palette[i] = AV_RB24(buf); + buf += 3; + } +} + +#define EA_PREAMBLE_SIZE 8 +#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') + +static int cmv_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + CmvContext *s = avctx->priv_data; + const uint8_t *buf_end = buf + buf_size; + + if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { + cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); + return buf_size; + } + + if (avcodec_check_dimensions(s->avctx, s->width, s->height)) + return -1; + + /* shuffle */ + if (s->last2_frame.data[0]) + avctx->release_buffer(avctx, &s->last2_frame); + FFSWAP(AVFrame, s->last_frame, s->last2_frame); + FFSWAP(AVFrame, s->frame, s->last_frame); + + s->frame.reference = 1; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; + if (avctx->get_buffer(avctx, &s->frame)<0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + + buf += EA_PREAMBLE_SIZE; + if ((buf[0]&1)) { // subtype + cmv_decode_inter(s, buf+2, buf_end); + s->frame.key_frame = 0; + s->frame.pict_type = FF_P_TYPE; + }else{ + s->frame.key_frame = 1; + s->frame.pict_type = FF_I_TYPE; + cmv_decode_intra(s, buf+2, buf_end); + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + return buf_size; +} + +static av_cold int cmv_decode_end(AVCodecContext *avctx){ + CmvContext *s = avctx->priv_data; + if (s->frame.data[0]) + s->avctx->release_buffer(avctx, &s->frame); + if (s->last_frame.data[0]) + s->avctx->release_buffer(avctx, &s->last_frame); + if (s->last2_frame.data[0]) + s->avctx->release_buffer(avctx, &s->last2_frame); + + return 0; +} + +AVCodec eacmv_decoder = { + "eacmv", + CODEC_TYPE_VIDEO, + CODEC_ID_CMV, + sizeof(CmvContext), + cmv_decode_init, + NULL, + cmv_decode_end, + cmv_decode_frame, + CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV Video"), +}; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/eval.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/eval.c @@ -59,7 +59,7 @@ typedef struct Parser{ double var[VARS]; } Parser; -static int8_t si_prefixes['z' - 'E' + 1]={ +static const int8_t si_prefixes['z' - 'E' + 1]={ ['y'-'E']= -24, ['z'-'E']= -21, ['a'-'E']= -18, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/faandct.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/faandct.c @@ -62,7 +62,7 @@ for(i=0; i<8; i++){ #define A5 0.38268343236508977170 // cos(pi*6/16) #define A4 1.30656296487637652774 // cos(pi*2/16)sqrt(2) -static FLOAT postscale[64]={ +static const FLOAT postscale[64]={ B0*B0, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B6, B0*B7, B1*B0, B1*B1, B1*B2, B1*B3, B1*B4, B1*B5, B1*B6, B1*B7, B2*B0, B2*B1, B2*B2, B2*B3, B2*B4, B2*B5, B2*B6, B2*B7, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/fft-test.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/fft-test.c @@ -33,8 +33,6 @@ #undef exit #undef random -int mm_flags; - /* reference fft */ #define MUL16(a,b) ((a) * (b)) @@ -188,7 +186,6 @@ int main(int argc, char **argv) MDCTContext m1, *m = &m1; int fft_nbits, fft_size; - mm_flags = 0; fft_nbits = 9; for(;;) { c = getopt(argc, argv, "hsimn:"); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/fft.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/fft.c @@ -59,6 +59,7 @@ int ff_fft_init(FFTContext *s, int nbits, int inverse) } s->fft_calc = ff_fft_calc_c; s->imdct_calc = ff_imdct_calc; + s->imdct_half = ff_imdct_half; s->exptab1 = NULL; #ifdef HAVE_MMX @@ -67,6 +68,7 @@ int ff_fft_init(FFTContext *s, int nbits, int inverse) if (has_vectors & MM_3DNOWEXT) { /* 3DNowEx for K7/K8 */ s->imdct_calc = ff_imdct_calc_3dn2; + s->imdct_half = ff_imdct_half_3dn2; s->fft_calc = ff_fft_calc_3dn2; } else if (has_vectors & MM_3DNOW) { /* 3DNow! for K6-2/3 */ @@ -74,6 +76,7 @@ int ff_fft_init(FFTContext *s, int nbits, int inverse) } else if (has_vectors & MM_SSE) { /* SSE for P3/P4 */ s->imdct_calc = ff_imdct_calc_sse; + s->imdct_half = ff_imdct_half_sse; s->fft_calc = ff_fft_calc_sse; } else { shuffle = 0; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ffv1.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ffv1.c @@ -34,6 +34,8 @@ #define MAX_PLANES 4 #define CONTEXT_SIZE 32 +extern const uint8_t ff_log2_run[32]; + static const int8_t quant3[256]={ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -143,12 +145,6 @@ static const int8_t quant13[256]={ -4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1, }; -static const uint8_t log2_run[32]={ - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 9,10,11,12,13,14,15, -}; - typedef struct VlcState{ int16_t drift; uint16_t error_sum; @@ -396,13 +392,13 @@ static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], in if(run_mode){ if(diff){ - while(run_count >= 1<<log2_run[run_index]){ - run_count -= 1<<log2_run[run_index]; + while(run_count >= 1<<ff_log2_run[run_index]){ + run_count -= 1<<ff_log2_run[run_index]; run_index++; put_bits(&s->pb, 1, 1); } - put_bits(&s->pb, 1 + log2_run[run_index], run_count); + put_bits(&s->pb, 1 + ff_log2_run[run_index], run_count); if(run_index) run_index--; run_count=0; run_mode=0; @@ -419,8 +415,8 @@ static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], in } } if(run_mode){ - while(run_count >= 1<<log2_run[run_index]){ - run_count -= 1<<log2_run[run_index]; + while(run_count >= 1<<ff_log2_run[run_index]){ + run_count -= 1<<ff_log2_run[run_index]; run_index++; put_bits(&s->pb, 1, 1); } @@ -735,10 +731,10 @@ static inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], i if(run_mode){ if(run_count==0 && run_mode==1){ if(get_bits1(&s->gb)){ - run_count = 1<<log2_run[run_index]; + run_count = 1<<ff_log2_run[run_index]; if(x + run_count <= w) run_index++; }else{ - if(log2_run[run_index]) run_count = get_bits(&s->gb, log2_run[run_index]); + if(ff_log2_run[run_index]) run_count = get_bits(&s->gb, ff_log2_run[run_index]); else run_count=0; if(run_index) run_index--; run_mode=2; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/flac.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/flac.c @@ -68,22 +68,22 @@ typedef struct FLACContext { int32_t *decoded[MAX_CHANNELS]; uint8_t *bitstream; - int bitstream_size; - int bitstream_index; + unsigned int bitstream_size; + unsigned int bitstream_index; unsigned int allocated_bitstream_size; } FLACContext; #define METADATA_TYPE_STREAMINFO 0 -static int sample_rate_table[] = +static const int sample_rate_table[] = { 0, 0, 0, 0, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 0, 0, 0, 0 }; -static int sample_size_table[] = +static const int sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 }; -static int blocksize_table[] = { +static const int blocksize_table[] = { 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, 256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 }; @@ -139,7 +139,8 @@ static void allocate_buffers(FLACContext *s){ s->decoded[i] = av_realloc(s->decoded[i], sizeof(int32_t)*s->max_blocksize); } - s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); + if(s->allocated_bitstream_size < s->max_framesize) + s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); } void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, @@ -180,6 +181,7 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, static int metadata_parse(FLACContext *s) { int i, metadata_last, metadata_type, metadata_size, streaminfo_updated=0; + int initial_pos= get_bits_count(&s->gb); if (show_bits_long(&s->gb, 32) == MKBETAG('f','L','a','C')) { skip_bits(&s->gb, 32); @@ -190,6 +192,11 @@ static int metadata_parse(FLACContext *s) metadata_type = get_bits(&s->gb, 7); metadata_size = get_bits_long(&s->gb, 24); + if(get_bits_count(&s->gb) + 8*metadata_size > s->gb.size_in_bits){ + skip_bits_long(&s->gb, initial_pos - get_bits_count(&s->gb)); + break; + } + av_log(s->avctx, AV_LOG_DEBUG, " metadata block: flag = %d, type = %d, size = %d\n", metadata_last, metadata_type, metadata_size); @@ -611,9 +618,16 @@ static int flac_decode_frame(AVCodecContext *avctx, } if(1 && s->max_framesize){//FIXME truncated - buf_size= FFMAX(FFMIN(buf_size, s->max_framesize - s->bitstream_size), 0); + if(s->bitstream_size < 4 || AV_RL32(s->bitstream) != MKTAG('f','L','a','C')) + buf_size= FFMIN(buf_size, s->max_framesize - FFMIN(s->bitstream_size, s->max_framesize)); input_buf_size= buf_size; + if(s->bitstream_size + buf_size < buf_size || s->bitstream_index + s->bitstream_size + buf_size < s->bitstream_index) + return -1; + + if(s->allocated_bitstream_size < s->bitstream_size + buf_size) + s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->bitstream_size + buf_size); + if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){ // printf("memmove\n"); memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); @@ -624,7 +638,7 @@ static int flac_decode_frame(AVCodecContext *avctx, buf_size += s->bitstream_size; s->bitstream_size= buf_size; - if(buf_size < s->max_framesize){ + if(buf_size < s->max_framesize && input_buf_size){ // printf("wanna more data ...\n"); return input_buf_size; } @@ -632,8 +646,9 @@ static int flac_decode_frame(AVCodecContext *avctx, init_get_bits(&s->gb, buf, buf_size*8); - if (!metadata_parse(s)) - { + if(metadata_parse(s)) + goto end; + tmp = show_bits(&s->gb, 16); if((tmp & 0xFFFE) != 0xFFF8){ av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); @@ -648,7 +663,6 @@ static int flac_decode_frame(AVCodecContext *avctx, s->bitstream_index=0; return -1; } - } #if 0 @@ -773,6 +787,7 @@ AVCodec flac_decoder = { NULL, flac_decode_close, flac_decode_frame, + CODEC_CAP_DELAY, .flush= flac_flush, .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/flacenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/flacenc.c @@ -1236,13 +1236,6 @@ static void channel_decorrelation(FlacEncodeContext *ctx) } } -static void put_sbits(PutBitContext *pb, int bits, int32_t val) -{ - assert(bits >= 0 && bits <= 31); - - put_bits(pb, bits, val & ((1<<bits)-1)); -} - static void write_utf8(PutBitContext *pb, uint32_t val) { uint8_t tmp; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/golomb.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/golomb.h @@ -469,7 +469,7 @@ static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int lim } put_bits(pb, e, 1); if(k) - put_bits(pb, k, i&((1<<k)-1)); + put_sbits(pb, k, i); }else{ while(limit > 31) { put_bits(pb, 31, 0); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h261enc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h261enc.c @@ -61,7 +61,7 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp - put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ + put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */ put_bits(&s->pb, 1, 0); /* split screen off */ put_bits(&s->pb, 1, 0); /* camera off */ @@ -309,7 +309,7 @@ static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ put_bits(&s->pb, 6, run); assert(slevel != 0); assert(level <= 127); - put_bits(&s->pb, 8, slevel & 0xff); + put_sbits(&s->pb, 8, slevel); } else { put_bits(&s->pb, 1, sign); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h263.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h263.c @@ -249,7 +249,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 22, 0x20); /* PSC */ temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->time_base.num / //FIXME use timestamp (coded_frame_rate_base * (int64_t)s->avctx->time_base.den); - put_bits(&s->pb, 8, temp_ref & 0xff); /* TemporalReference */ + put_sbits(&s->pb, 8, temp_ref); /* TemporalReference */ put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, 1, 0); /* h263 id */ @@ -326,7 +326,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 1, best_clock_code); put_bits(&s->pb, 7, best_divisor); } - put_bits(&s->pb, 2, (temp_ref>>8)&3); + put_sbits(&s->pb, 2, temp_ref>>8); } /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ @@ -2224,11 +2224,11 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) assert(slevel != 0); if(level < 128) - put_bits(&s->pb, 8, slevel & 0xff); + put_sbits(&s->pb, 8, slevel); else{ put_bits(&s->pb, 8, 128); - put_bits(&s->pb, 5, slevel & 0x1f); - put_bits(&s->pb, 6, (slevel>>5)&0x3f); + put_sbits(&s->pb, 5, slevel); + put_sbits(&s->pb, 6, slevel>>5); } }else{ if(level < 64) { // 7-bit level @@ -2236,14 +2236,14 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) put_bits(&s->pb, 1, last); put_bits(&s->pb, 6, run); - put_bits(&s->pb, 7, slevel & 0x7f); + put_sbits(&s->pb, 7, slevel); } else { /* 11-bit level */ put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, last); put_bits(&s->pb, 6, run); - put_bits(&s->pb, 11, slevel & 0x7ff); + put_sbits(&s->pb, 11, slevel); } } } else { @@ -2804,7 +2804,7 @@ static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n put_bits(ac_pb, 1, last); put_bits(ac_pb, 6, run); put_bits(ac_pb, 1, 1); - put_bits(ac_pb, 12, slevel & 0xfff); + put_sbits(ac_pb, 12, slevel); put_bits(ac_pb, 1, 1); } else { /* second escape */ @@ -2907,18 +2907,18 @@ void h263_decode_init_vlc(MpegEncContext *s) if (!done) { done = 1; - init_vlc(&intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9, + INIT_VLC_STATIC(&intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9, intra_MCBPC_bits, 1, 1, - intra_MCBPC_code, 1, 1, 1); - init_vlc(&inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28, + intra_MCBPC_code, 1, 1, 72); + INIT_VLC_STATIC(&inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28, inter_MCBPC_bits, 1, 1, - inter_MCBPC_code, 1, 1, 1); - init_vlc(&cbpy_vlc, CBPY_VLC_BITS, 16, + inter_MCBPC_code, 1, 1, 198); + INIT_VLC_STATIC(&cbpy_vlc, CBPY_VLC_BITS, 16, &cbpy_tab[0][1], 2, 1, - &cbpy_tab[0][0], 2, 1, 1); - init_vlc(&mv_vlc, MV_VLC_BITS, 33, + &cbpy_tab[0][0], 2, 1, 64); + INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 33, &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 1); + &mvtab[0][0], 2, 1, 538); init_rl(&rl_inter, static_rl_table_store[0]); init_rl(&rl_intra, static_rl_table_store[1]); init_rl(&rvlc_rl_inter, static_rl_table_store[3]); @@ -2929,24 +2929,24 @@ void h263_decode_init_vlc(MpegEncContext *s) INIT_VLC_RL(rvlc_rl_inter, 1072); INIT_VLC_RL(rvlc_rl_intra, 1072); INIT_VLC_RL(rl_intra_aic, 554); - init_vlc(&dc_lum, DC_VLC_BITS, 10 /* 13 */, + INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, &DCtab_lum[0][1], 2, 1, - &DCtab_lum[0][0], 2, 1, 1); - init_vlc(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, + &DCtab_lum[0][0], 2, 1, 512); + INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, &DCtab_chrom[0][1], 2, 1, - &DCtab_chrom[0][0], 2, 1, 1); - init_vlc(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, + &DCtab_chrom[0][0], 2, 1, 512); + INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, &sprite_trajectory_tab[0][1], 4, 2, - &sprite_trajectory_tab[0][0], 4, 2, 1); - init_vlc(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, + &sprite_trajectory_tab[0][0], 4, 2, 128); + INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, &mb_type_b_tab[0][1], 2, 1, - &mb_type_b_tab[0][0], 2, 1, 1); - init_vlc(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15, + &mb_type_b_tab[0][0], 2, 1, 16); + INIT_VLC_STATIC(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15, &h263_mbtype_b_tab[0][1], 2, 1, - &h263_mbtype_b_tab[0][0], 2, 1, 1); - init_vlc(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4, + &h263_mbtype_b_tab[0][0], 2, 1, 80); + INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4, &cbpc_b_tab[0][1], 2, 1, - &cbpc_b_tab[0][0], 2, 1, 1); + &cbpc_b_tab[0][0], 2, 1, 8); } } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h264.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h264.c @@ -2200,7 +2200,11 @@ static av_cold int decode_init(AVCodecContext *avctx){ // s->decode_mb= ff_h263_decode_mb; s->quarter_sample = 1; s->low_delay= 1; - avctx->pix_fmt= PIX_FMT_YUV420P; + + if(avctx->codec_id == CODEC_ID_SVQ3) + avctx->pix_fmt= PIX_FMT_YUVJ420P; + else + avctx->pix_fmt= PIX_FMT_YUV420P; decode_init_vlc(); @@ -2255,6 +2259,15 @@ static int frame_start(H264Context *h){ memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(uint8_t)); // s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1; + + // We mark the current picture as non reference after allocating it, so + // that if we break out due to an error it can be released automatically + // in the next MPV_frame_start(). + // SVQ3 as well as most other codecs have only last/next/current and thus + // get released even with set reference, besides SVQ3 and others do not + // mark frames as reference later "naturally". + if(s->codec_id != CODEC_ID_SVQ3) + s->current_picture_ptr->reference= 0; return 0; } @@ -2726,9 +2739,10 @@ static void hl_decode_mb(H264Context *h){ MpegEncContext * const s = &h->s; const int mb_xy= h->mb_xy; const int mb_type= s->current_picture.mb_type[mb_xy]; - int is_complex = FRAME_MBAFF || MB_FIELD || IS_INTRA_PCM(mb_type) || s->codec_id != CODEC_ID_H264 || (ENABLE_GRAY && (s->flags&CODEC_FLAG_GRAY)) || s->encoding; + int is_complex = FRAME_MBAFF || MB_FIELD || IS_INTRA_PCM(mb_type) || s->codec_id != CODEC_ID_H264 || + (ENABLE_GRAY && (s->flags&CODEC_FLAG_GRAY)) || (ENABLE_H264_ENCODER && s->encoding) || ENABLE_SMALL; - if(!s->decode) + if(ENABLE_H264_ENCODER && !s->decode) return; if (is_complex) @@ -3263,15 +3277,11 @@ static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ if (pic->reference &= refmask) { return 0; } else { - if(pic == h->delayed_output_pic) - pic->reference=DELAYED_PIC_REF; - else{ - for(i = 0; h->delayed_pic[i]; i++) - if(pic == h->delayed_pic[i]){ - pic->reference=DELAYED_PIC_REF; - break; - } - } + for(i = 0; h->delayed_pic[i]; i++) + if(pic == h->delayed_pic[i]){ + pic->reference=DELAYED_PIC_REF; + break; + } return 1; } } @@ -3301,14 +3311,12 @@ static void idr(H264Context *h){ static void flush_dpb(AVCodecContext *avctx){ H264Context *h= avctx->priv_data; int i; - for(i=0; i<16; i++) { + for(i=0; i<MAX_DELAYED_PIC_COUNT; i++) { if(h->delayed_pic[i]) h->delayed_pic[i]->reference= 0; h->delayed_pic[i]= NULL; } - if(h->delayed_output_pic) - h->delayed_output_pic->reference= 0; - h->delayed_output_pic= NULL; + h->outputed_poc= INT_MIN; idr(h); if(h->s.current_picture_ptr) h->s.current_picture_ptr->reference= 0; @@ -3347,7 +3355,7 @@ static Picture * find_short(H264Context *h, int frame_num, int *idx){ * @param i index into h->short_ref of picture to remove. */ static void remove_short_at_index(H264Context *h, int i){ - assert(i > 0 && i < h->short_ref_count); + assert(i >= 0 && i < h->short_ref_count); h->short_ref[i]= NULL; if (--h->short_ref_count) memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i)*sizeof(Picture*)); @@ -4351,12 +4359,11 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in level_code= (prefix<<suffix_length) + get_bits(gb, suffix_length); //part else level_code= prefix + get_bits(gb, 4); //part - }else if(prefix==15){ - level_code= (prefix<<suffix_length) + get_bits(gb, 12); //part - if(suffix_length==0) level_code+=15; //FIXME doesn't make (much)sense }else{ - av_log(h->s.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y); - return -1; + level_code= (15<<suffix_length) + get_bits(gb, prefix-3); //part + if(suffix_length==0) level_code+=15; //FIXME doesn't make (much)sense + if(prefix>=16) + level_code += (1<<(prefix-3))-4096; } if(trailing_ones < 3) level_code += 2; @@ -4374,11 +4381,10 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in prefix = get_level_prefix(gb); if(prefix<15){ level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length); - }else if(prefix==15){ - level_code = (prefix<<suffix_length) + get_bits(gb, 12); }else{ - av_log(h->s.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y); - return -1; + level_code = (15<<suffix_length) + get_bits(gb, prefix-3); + if(prefix>=16) + level_code += (1<<(prefix-3))-4096; } mask= -(level_code&1); level[i]= (((2+level_code)>>1) ^ mask) - mask; @@ -5337,23 +5343,27 @@ static int decode_cabac_mb_mvd( H264Context *h, int list, int n, int l ) { return get_cabac_bypass_sign( &h->cabac, -mvd ); } -static inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { +static av_always_inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx, int is_dc ) { int nza, nzb; int ctx = 0; - if( cat == 0 ) { - nza = h->left_cbp&0x100; - nzb = h-> top_cbp&0x100; - } else if( cat == 1 || cat == 2 ) { - nza = h->non_zero_count_cache[scan8[idx] - 1]; - nzb = h->non_zero_count_cache[scan8[idx] - 8]; - } else if( cat == 3 ) { - nza = (h->left_cbp>>(6+idx))&0x01; - nzb = (h-> top_cbp>>(6+idx))&0x01; + if( is_dc ) { + if( cat == 0 ) { + nza = h->left_cbp&0x100; + nzb = h-> top_cbp&0x100; + } else { + nza = (h->left_cbp>>(6+idx))&0x01; + nzb = (h-> top_cbp>>(6+idx))&0x01; + } } else { - assert(cat == 4); - nza = h->non_zero_count_cache[scan8[16+idx] - 1]; - nzb = h->non_zero_count_cache[scan8[16+idx] - 8]; + if( cat == 4 ) { + nza = h->non_zero_count_cache[scan8[16+idx] - 1]; + nzb = h->non_zero_count_cache[scan8[16+idx] - 8]; + } else { + assert(cat == 1 || cat == 2); + nza = h->non_zero_count_cache[scan8[idx] - 1]; + nzb = h->non_zero_count_cache[scan8[idx] - 8]; + } } if( nza > 0 ) @@ -5372,7 +5382,7 @@ DECLARE_ASM_CONST(1, uint8_t, last_coeff_flag_offset_8x8[63]) = { 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8 }; -static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff) { +static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff, int is_dc ) { static const int significant_coeff_flag_offset[2][6] = { { 105+0, 105+15, 105+29, 105+44, 105+47, 402 }, { 277+0, 277+15, 277+29, 277+44, 277+47, 436 } @@ -5440,12 +5450,15 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int */ /* read coded block flag */ - if( cat != 5 ) { - if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n ) ] ) == 0 ) { - if( cat == 1 || cat == 2 ) - h->non_zero_count_cache[scan8[n]] = 0; - else if( cat == 4 ) - h->non_zero_count_cache[scan8[16+n]] = 0; + if( is_dc || cat != 5 ) { + if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n, is_dc ) ] ) == 0 ) { + if( !is_dc ) { + if( cat == 4 ) + h->non_zero_count_cache[scan8[16+n]] = 0; + else + h->non_zero_count_cache[scan8[n]] = 0; + } + #ifdef CABAC_ON_STACK h->cabac.range = cc.range ; h->cabac.low = cc.low ; @@ -5462,7 +5475,7 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int abs_level_m1_ctx_base = h->cabac_state + coeff_abs_level_m1_offset[cat]; - if( cat == 5 ) { + if( !is_dc && cat == 5 ) { #define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \ for(last= 0; last < coefs; last++) { \ uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \ @@ -5491,27 +5504,30 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int } assert(coeff_count > 0); - if( cat == 0 ) - h->cbp_table[h->mb_xy] |= 0x100; - else if( cat == 1 || cat == 2 ) - h->non_zero_count_cache[scan8[n]] = coeff_count; - else if( cat == 3 ) - h->cbp_table[h->mb_xy] |= 0x40 << n; - else if( cat == 4 ) - h->non_zero_count_cache[scan8[16+n]] = coeff_count; - else { - assert( cat == 5 ); - fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1); + if( is_dc ) { + if( cat == 0 ) + h->cbp_table[h->mb_xy] |= 0x100; + else + h->cbp_table[h->mb_xy] |= 0x40 << n; + } else { + if( cat == 5 ) + fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1); + else if( cat == 4 ) + h->non_zero_count_cache[scan8[16+n]] = coeff_count; + else { + assert( cat == 1 || cat == 2 ); + h->non_zero_count_cache[scan8[n]] = coeff_count; + } } - for( coeff_count--; coeff_count >= 0; coeff_count-- ) { + while( coeff_count-- ) { uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; int j= scantable[index[coeff_count]]; if( get_cabac( CC, ctx ) == 0 ) { node_ctx = coeff_abs_level_transition[0][node_ctx]; - if( !qmul ) { + if( is_dc ) { block[j] = get_cabac_bypass_sign( CC, -1); }else{ block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; @@ -5538,12 +5554,10 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int coeff_abs+= 14; } - if( !qmul ) { - if( get_cabac_bypass( CC ) ) block[j] = -coeff_abs; - else block[j] = coeff_abs; + if( is_dc ) { + block[j] = get_cabac_bypass_sign( CC, -coeff_abs ); }else{ - if( get_cabac_bypass( CC ) ) block[j] = (-coeff_abs * qmul[j] + 32) >> 6; - else block[j] = ( coeff_abs * qmul[j] + 32) >> 6; + block[j] = (get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32) >> 6; } } } @@ -5555,6 +5569,25 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int } +#ifndef CONFIG_SMALL +static void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { + decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 1); +} + +static void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { + decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0); +} +#endif + +static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { +#ifdef CONFIG_SMALL + decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, cat == 0 || cat == 3); +#else + if( cat == 0 || cat == 3 ) decode_cabac_residual_dc(h, block, cat, n, scantable, qmul, max_coeff); + else decode_cabac_residual_nondc(h, block, cat, n, scantable, qmul, max_coeff); +#endif +} + static inline void compute_mb_neighbors(H264Context *h) { MpegEncContext * const s = &h->s; @@ -5720,6 +5753,7 @@ decode_intra_mb: // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 16); s->current_picture.mb_type[mb_xy]= mb_type; + h->last_qscale_diff = 0; return 0; } @@ -6461,7 +6495,7 @@ static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, int step = IS_8x8DCT(mb_type) ? 2 : 1; edges = (mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4; s->dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache, - (h->slice_type == FF_B_TYPE), edges, step, mask_edge0, mask_edge1 ); + (h->slice_type == FF_B_TYPE), edges, step, mask_edge0, mask_edge1, FIELD_PICTURE); } if( IS_INTRA(s->current_picture.mb_type[mb_xy-1]) ) bSv[0][0] = 0x0004000400040004ULL; @@ -7751,7 +7785,6 @@ static int decode_frame(AVCodecContext *avctx, if(!(s->flags2 & CODEC_FLAG2_CHUNKS) || (s->mb_y >= s->mb_height && s->mb_height)){ Picture *out = s->current_picture_ptr; Picture *cur = s->current_picture_ptr; - Picture *prev = h->delayed_output_pic; int i, pics, cross_idr, out_of_order, out_idx; s->mb_y= 0; @@ -7795,9 +7828,6 @@ static int decode_frame(AVCodecContext *avctx, //FIXME do something with unavailable reference frames -#if 0 //decode order - *data_size = sizeof(AVFrame); -#else /* Sort B-frames into display order */ if(h->sps.bitstream_restriction_flag @@ -7806,10 +7836,16 @@ static int decode_frame(AVCodecContext *avctx, s->low_delay = 0; } + if( s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT + && !h->sps.bitstream_restriction_flag){ + s->avctx->has_b_frames= MAX_DELAYED_PIC_COUNT; + s->low_delay= 0; + } + pics = 0; while(h->delayed_pic[pics]) pics++; - assert(pics+1 < sizeof(h->delayed_pic) / sizeof(h->delayed_pic[0])); + assert(pics <= MAX_DELAYED_PIC_COUNT); h->delayed_pic[pics++] = cur; if(cur->reference == 0) @@ -7828,41 +7864,32 @@ static int decode_frame(AVCodecContext *avctx, out_idx = i; } - out_of_order = !cross_idr && prev && out->poc < prev->poc; + out_of_order = !cross_idr && out->poc < h->outputed_poc; + if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames) { } - else if(prev && pics <= s->avctx->has_b_frames) - out = prev; - else if((out_of_order && pics-1 == s->avctx->has_b_frames && pics < 15) + else if((out_of_order && pics-1 == s->avctx->has_b_frames && s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) || (s->low_delay && - ((!cross_idr && prev && out->poc > prev->poc + 2) + ((!cross_idr && out->poc > h->outputed_poc + 2) || cur->pict_type == FF_B_TYPE))) { s->low_delay = 0; s->avctx->has_b_frames++; - out = prev; } - else if(out_of_order) - out = prev; if(out_of_order || pics > s->avctx->has_b_frames){ + out->reference &= ~DELAYED_PIC_REF; for(i=out_idx; h->delayed_pic[i]; i++) h->delayed_pic[i] = h->delayed_pic[i+1]; } - - if(prev == out) - *data_size = 0; - else + if(!out_of_order && pics > s->avctx->has_b_frames){ *data_size = sizeof(AVFrame); - if(prev && prev != out && prev->reference == DELAYED_PIC_REF) - prev->reference = 0; - h->delayed_output_pic = out; -#endif - if(out) + h->outputed_poc = out->poc; *pict= *(AVFrame*)out; - else + }else{ av_log(avctx, AV_LOG_DEBUG, "no picture\n"); + } } } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h264.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/h264.h @@ -51,6 +51,8 @@ #define MAX_MMCO_COUNT 66 +#define MAX_DELAYED_PIC_COUNT 16 + /* Compiling in interlaced support reduces the speed * of progressive decoding by about 2%. */ #define ALLOW_INTERLACE @@ -70,6 +72,10 @@ #endif #define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE) +#ifndef ENABLE_H264_ENCODER +#define ENABLE_H264_ENCODER 0 +#endif + /** * Sequence parameter set */ @@ -330,8 +336,8 @@ typedef struct H264Context{ Picture ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs. Reordered version of default_ref_list according to picture reordering in slice header */ - Picture *delayed_pic[18]; //FIXME size? - Picture *delayed_output_pic; + Picture *delayed_pic[MAX_DELAYED_PIC_COUNT+2]; //FIXME size? + int outputed_poc; /** * memory management control operations buffer. diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/dsputil_mmx.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/dsputil_mmx.c @@ -482,6 +482,7 @@ static void clear_blocks_mmx(DCTELEM *blocks) static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ x86_reg i=0; asm volatile( + "jmp 2f \n\t" "1: \n\t" "movq (%1, %0), %%mm0 \n\t" "movq (%2, %0), %%mm1 \n\t" @@ -492,8 +493,9 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ "paddb %%mm0, %%mm1 \n\t" "movq %%mm1, 8(%2, %0) \n\t" "add $16, %0 \n\t" + "2: \n\t" "cmp %3, %0 \n\t" - " jb 1b \n\t" + " js 1b \n\t" : "+r" (i) : "r"(src), "r"(dst), "r"((x86_reg)w-15) ); @@ -504,6 +506,7 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ x86_reg i=0; asm volatile( + "jmp 2f \n\t" "1: \n\t" "movq (%2, %0), %%mm0 \n\t" "movq 8(%2, %0), %%mm1 \n\t" @@ -512,8 +515,9 @@ static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ "movq %%mm0, (%1, %0) \n\t" "movq %%mm1, 8(%1, %0) \n\t" "add $16, %0 \n\t" + "2: \n\t" "cmp %4, %0 \n\t" - " jb 1b \n\t" + " js 1b \n\t" : "+r" (i) : "r"(dst), "r"(src1), "r"(src2), "r"((x86_reg)w-15) ); @@ -2018,36 +2022,219 @@ static void vector_fmul_add_add_sse(float *dst, const float *src0, const float * ff_vector_fmul_add_add_c(dst, src0, src1, src2, src3, len, step); } -static void float_to_int16_3dnow(int16_t *dst, const float *src, int len){ - // not bit-exact: pf2id uses different rounding than C and SSE - int i; - for(i=0; i<len; i+=4) { +static void vector_fmul_window_3dnow2(float *dst, const float *src0, const float *src1, + const float *win, float add_bias, int len){ +#ifdef HAVE_6REGS + if(add_bias == 0){ + x86_reg i = -len*4; + x86_reg j = len*4-8; asm volatile( - "pf2id %1, %%mm0 \n\t" - "pf2id %2, %%mm1 \n\t" - "packssdw %%mm1, %%mm0 \n\t" - "movq %%mm0, %0 \n\t" - :"=m"(dst[i]) - :"m"(src[i]), "m"(src[i+2]) + "1: \n" + "pswapd (%5,%1), %%mm1 \n" + "movq (%5,%0), %%mm0 \n" + "pswapd (%4,%1), %%mm5 \n" + "movq (%3,%0), %%mm4 \n" + "movq %%mm0, %%mm2 \n" + "movq %%mm1, %%mm3 \n" + "pfmul %%mm4, %%mm2 \n" // src0[len+i]*win[len+i] + "pfmul %%mm5, %%mm3 \n" // src1[ j]*win[len+j] + "pfmul %%mm4, %%mm1 \n" // src0[len+i]*win[len+j] + "pfmul %%mm5, %%mm0 \n" // src1[ j]*win[len+i] + "pfadd %%mm3, %%mm2 \n" + "pfsub %%mm0, %%mm1 \n" + "pswapd %%mm2, %%mm2 \n" + "movq %%mm1, (%2,%0) \n" + "movq %%mm2, (%2,%1) \n" + "sub $8, %1 \n" + "add $8, %0 \n" + "jl 1b \n" + "femms \n" + :"+r"(i), "+r"(j) + :"r"(dst+len), "r"(src0+len), "r"(src1), "r"(win+len) ); - } - asm volatile("femms"); + }else +#endif + ff_vector_fmul_window_c(dst, src0, src1, win, add_bias, len); } -static void float_to_int16_sse(int16_t *dst, const float *src, int len){ - int i; - for(i=0; i<len; i+=4) { + +static void vector_fmul_window_sse(float *dst, const float *src0, const float *src1, + const float *win, float add_bias, int len){ +#ifdef HAVE_6REGS + if(add_bias == 0){ + x86_reg i = -len*4; + x86_reg j = len*4-16; asm volatile( - "cvtps2pi %1, %%mm0 \n\t" - "cvtps2pi %2, %%mm1 \n\t" - "packssdw %%mm1, %%mm0 \n\t" - "movq %%mm0, %0 \n\t" - :"=m"(dst[i]) - :"m"(src[i]), "m"(src[i+2]) + "1: \n" + "movaps (%5,%1), %%xmm1 \n" + "movaps (%5,%0), %%xmm0 \n" + "movaps (%4,%1), %%xmm5 \n" + "movaps (%3,%0), %%xmm4 \n" + "shufps $0x1b, %%xmm1, %%xmm1 \n" + "shufps $0x1b, %%xmm5, %%xmm5 \n" + "movaps %%xmm0, %%xmm2 \n" + "movaps %%xmm1, %%xmm3 \n" + "mulps %%xmm4, %%xmm2 \n" // src0[len+i]*win[len+i] + "mulps %%xmm5, %%xmm3 \n" // src1[ j]*win[len+j] + "mulps %%xmm4, %%xmm1 \n" // src0[len+i]*win[len+j] + "mulps %%xmm5, %%xmm0 \n" // src1[ j]*win[len+i] + "addps %%xmm3, %%xmm2 \n" + "subps %%xmm0, %%xmm1 \n" + "shufps $0x1b, %%xmm2, %%xmm2 \n" + "movaps %%xmm1, (%2,%0) \n" + "movaps %%xmm2, (%2,%1) \n" + "sub $16, %1 \n" + "add $16, %0 \n" + "jl 1b \n" + :"+r"(i), "+r"(j) + :"r"(dst+len), "r"(src0+len), "r"(src1), "r"(win+len) ); - } - asm volatile("emms"); + }else +#endif + ff_vector_fmul_window_c(dst, src0, src1, win, add_bias, len); +} + +static void float_to_int16_3dnow(int16_t *dst, const float *src, long len){ + // not bit-exact: pf2id uses different rounding than C and SSE + asm volatile( + "add %0 , %0 \n\t" + "lea (%2,%0,2) , %2 \n\t" + "add %0 , %1 \n\t" + "neg %0 \n\t" + "1: \n\t" + "pf2id (%2,%0,2) , %%mm0 \n\t" + "pf2id 8(%2,%0,2) , %%mm1 \n\t" + "pf2id 16(%2,%0,2) , %%mm2 \n\t" + "pf2id 24(%2,%0,2) , %%mm3 \n\t" + "packssdw %%mm1 , %%mm0 \n\t" + "packssdw %%mm3 , %%mm2 \n\t" + "movq %%mm0 , (%1,%0) \n\t" + "movq %%mm2 , 8(%1,%0) \n\t" + "add $16 , %0 \n\t" + " js 1b \n\t" + "femms \n\t" + :"+r"(len), "+r"(dst), "+r"(src) + ); +} +static void float_to_int16_sse(int16_t *dst, const float *src, long len){ + asm volatile( + "add %0 , %0 \n\t" + "lea (%2,%0,2) , %2 \n\t" + "add %0 , %1 \n\t" + "neg %0 \n\t" + "1: \n\t" + "cvtps2pi (%2,%0,2) , %%mm0 \n\t" + "cvtps2pi 8(%2,%0,2) , %%mm1 \n\t" + "cvtps2pi 16(%2,%0,2) , %%mm2 \n\t" + "cvtps2pi 24(%2,%0,2) , %%mm3 \n\t" + "packssdw %%mm1 , %%mm0 \n\t" + "packssdw %%mm3 , %%mm2 \n\t" + "movq %%mm0 , (%1,%0) \n\t" + "movq %%mm2 , 8(%1,%0) \n\t" + "add $16 , %0 \n\t" + " js 1b \n\t" + "emms \n\t" + :"+r"(len), "+r"(dst), "+r"(src) + ); +} + +static void float_to_int16_sse2(int16_t *dst, const float *src, long len){ + asm volatile( + "add %0 , %0 \n\t" + "lea (%2,%0,2) , %2 \n\t" + "add %0 , %1 \n\t" + "neg %0 \n\t" + "1: \n\t" + "cvtps2dq (%2,%0,2) , %%xmm0 \n\t" + "cvtps2dq 16(%2,%0,2) , %%xmm1 \n\t" + "packssdw %%xmm1 , %%xmm0 \n\t" + "movdqa %%xmm0 , (%1,%0) \n\t" + "add $16 , %0 \n\t" + " js 1b \n\t" + :"+r"(len), "+r"(dst), "+r"(src) + ); } +#define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \ +/* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\ +static av_noinline void float_to_int16_interleave2_##cpu(int16_t *dst, const float **src, long len, int channels){\ + DECLARE_ALIGNED_16(int16_t, tmp[len]);\ + int i,j,c;\ + for(c=0; c<channels; c++){\ + float_to_int16_##cpu(tmp, src[c], len);\ + for(i=0, j=c; i<len; i++, j+=channels)\ + dst[j] = tmp[i];\ + }\ +}\ +\ +static void float_to_int16_interleave_##cpu(int16_t *dst, const float **src, long len, int channels){\ + if(channels==1)\ + float_to_int16_##cpu(dst, src[0], len);\ + else if(channels>2)\ + float_to_int16_interleave2_##cpu(dst, src, len, channels);\ + else{\ + const float *src0 = src[0];\ + const float *src1 = src[1];\ + asm volatile(\ + "shl $2, %0 \n"\ + "add %0, %1 \n"\ + "add %0, %2 \n"\ + "add %0, %3 \n"\ + "neg %0 \n"\ + body\ + :"+r"(len), "+r"(dst), "+r"(src0), "+r"(src1)\ + );\ + }\ +} + +FLOAT_TO_INT16_INTERLEAVE(3dnow, + "1: \n" + "pf2id (%2,%0), %%mm0 \n" + "pf2id 8(%2,%0), %%mm1 \n" + "pf2id (%3,%0), %%mm2 \n" + "pf2id 8(%3,%0), %%mm3 \n" + "packssdw %%mm1, %%mm0 \n" + "packssdw %%mm3, %%mm2 \n" + "movq %%mm0, %%mm1 \n" + "punpcklwd %%mm2, %%mm0 \n" + "punpckhwd %%mm2, %%mm1 \n" + "movq %%mm0, (%1,%0)\n" + "movq %%mm1, 8(%1,%0)\n" + "add $16, %0 \n" + "js 1b \n" + "femms \n" +) + +FLOAT_TO_INT16_INTERLEAVE(sse, + "1: \n" + "cvtps2pi (%2,%0), %%mm0 \n" + "cvtps2pi 8(%2,%0), %%mm1 \n" + "cvtps2pi (%3,%0), %%mm2 \n" + "cvtps2pi 8(%3,%0), %%mm3 \n" + "packssdw %%mm1, %%mm0 \n" + "packssdw %%mm3, %%mm2 \n" + "movq %%mm0, %%mm1 \n" + "punpcklwd %%mm2, %%mm0 \n" + "punpckhwd %%mm2, %%mm1 \n" + "movq %%mm0, (%1,%0)\n" + "movq %%mm1, 8(%1,%0)\n" + "add $16, %0 \n" + "js 1b \n" + "emms \n" +) + +FLOAT_TO_INT16_INTERLEAVE(sse2, + "1: \n" + "cvtps2dq (%2,%0), %%xmm0 \n" + "cvtps2dq (%3,%0), %%xmm1 \n" + "packssdw %%xmm1, %%xmm0 \n" + "movhlps %%xmm0, %%xmm1 \n" + "punpcklwd %%xmm1, %%xmm0 \n" + "movdqa %%xmm0, (%1,%0) \n" + "add $16, %0 \n" + "js 1b \n" +) + + extern void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, int width); extern void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, int width); extern void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); @@ -2057,6 +2244,79 @@ extern void ff_snow_inner_add_yblock_sse2(const uint8_t *obmc, const int obmc_st extern void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); + +static void add_int16_sse2(int16_t * v1, int16_t * v2, int order) +{ + x86_reg o = -(order << 1); + v1 += order; + v2 += order; + asm volatile( + "1: \n\t" + "movdqu (%1,%2), %%xmm0 \n\t" + "movdqu 16(%1,%2), %%xmm1 \n\t" + "paddw (%0,%2), %%xmm0 \n\t" + "paddw 16(%0,%2), %%xmm1 \n\t" + "movdqa %%xmm0, (%0,%2) \n\t" + "movdqa %%xmm1, 16(%0,%2) \n\t" + "add $32, %2 \n\t" + "js 1b \n\t" + : "+r"(v1), "+r"(v2), "+r"(o) + ); +} + +static void sub_int16_sse2(int16_t * v1, int16_t * v2, int order) +{ + x86_reg o = -(order << 1); + v1 += order; + v2 += order; + asm volatile( + "1: \n\t" + "movdqa (%0,%2), %%xmm0 \n\t" + "movdqa 16(%0,%2), %%xmm2 \n\t" + "movdqu (%1,%2), %%xmm1 \n\t" + "movdqu 16(%1,%2), %%xmm3 \n\t" + "psubw %%xmm1, %%xmm0 \n\t" + "psubw %%xmm3, %%xmm2 \n\t" + "movdqa %%xmm0, (%0,%2) \n\t" + "movdqa %%xmm2, 16(%0,%2) \n\t" + "add $32, %2 \n\t" + "js 1b \n\t" + : "+r"(v1), "+r"(v2), "+r"(o) + ); +} + +static int32_t scalarproduct_int16_sse2(int16_t * v1, int16_t * v2, int order, int shift) +{ + int res = 0; + DECLARE_ALIGNED_16(int64_t, sh); + x86_reg o = -(order << 1); + + v1 += order; + v2 += order; + sh = shift; + asm volatile( + "pxor %%xmm7, %%xmm7 \n\t" + "1: \n\t" + "movdqu (%0,%3), %%xmm0 \n\t" + "movdqu 16(%0,%3), %%xmm1 \n\t" + "pmaddwd (%1,%3), %%xmm0 \n\t" + "pmaddwd 16(%1,%3), %%xmm1 \n\t" + "paddd %%xmm0, %%xmm7 \n\t" + "paddd %%xmm1, %%xmm7 \n\t" + "add $32, %3 \n\t" + "js 1b \n\t" + "movhlps %%xmm7, %%xmm2 \n\t" + "paddd %%xmm2, %%xmm7 \n\t" + "psrad %4, %%xmm7 \n\t" + "pshuflw $0x4E, %%xmm7,%%xmm2 \n\t" + "paddd %%xmm2, %%xmm7 \n\t" + "movd %%xmm7, %2 \n\t" + : "+r"(v1), "+r"(v2), "=r"(res), "+r"(o) + : "m"(sh) + ); + return res; +} + void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) { mm_flags = mm_support(); @@ -2411,20 +2671,35 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) if(mm_flags & MM_3DNOW){ c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow; c->vector_fmul = vector_fmul_3dnow; - if(!(avctx->flags & CODEC_FLAG_BITEXACT)) + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ c->float_to_int16 = float_to_int16_3dnow; + c->float_to_int16_interleave = float_to_int16_interleave_3dnow; + } } - if(mm_flags & MM_3DNOWEXT) + if(mm_flags & MM_3DNOWEXT){ c->vector_fmul_reverse = vector_fmul_reverse_3dnow2; + c->vector_fmul_window = vector_fmul_window_3dnow2; + } if(mm_flags & MM_SSE){ c->vorbis_inverse_coupling = vorbis_inverse_coupling_sse; c->vector_fmul = vector_fmul_sse; c->float_to_int16 = float_to_int16_sse; + c->float_to_int16_interleave = float_to_int16_interleave_sse; c->vector_fmul_reverse = vector_fmul_reverse_sse; c->vector_fmul_add_add = vector_fmul_add_add_sse; + c->vector_fmul_window = vector_fmul_window_sse; + } + if(mm_flags & MM_SSE2){ + c->float_to_int16 = float_to_int16_sse2; + c->float_to_int16_interleave = float_to_int16_interleave_sse2; } if(mm_flags & MM_3DNOW) c->vector_fmul_add_add = vector_fmul_add_add_3dnow; // faster than sse + if(mm_flags & MM_SSE2){ + c->add_int16 = add_int16_sse2; + c->sub_int16 = sub_int16_sse2; + c->scalarproduct_int16 = scalarproduct_int16_sse2; + } } if (ENABLE_ENCODERS) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/dsputil_mmx.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/dsputil_mmx.h @@ -57,6 +57,18 @@ extern const uint64_t ff_pb_FC; extern const double ff_pd_1[2]; extern const double ff_pd_2[2]; +#define LOAD4(stride,in,a,b,c,d)\ + "movq 0*"#stride"+"#in", "#a"\n\t"\ + "movq 1*"#stride"+"#in", "#b"\n\t"\ + "movq 2*"#stride"+"#in", "#c"\n\t"\ + "movq 3*"#stride"+"#in", "#d"\n\t" + +#define STORE4(stride,out,a,b,c,d)\ + "movq "#a", 0*"#stride"+"#out"\n\t"\ + "movq "#b", 1*"#stride"+"#out"\n\t"\ + "movq "#c", 2*"#stride"+"#out"\n\t"\ + "movq "#d", 3*"#stride"+"#out"\n\t" + /* in/out: mma=mma+mmb, mmb=mmb-mma */ #define SUMSUB_BA( a, b ) \ "paddw "#b", "#a" \n\t"\ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/dsputilenc_mmx.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/dsputilenc_mmx.c @@ -998,18 +998,6 @@ static void sub_hfyu_median_prediction_mmx2(uint8_t *dst, uint8_t *src1, uint8_t "paddusw %%xmm1, %%xmm0 \n\t" #endif -#define LOAD4(o, a, b, c, d)\ - "movq "#o"(%1), "#a" \n\t"\ - "movq "#o"+8(%1), "#b" \n\t"\ - "movq "#o"+16(%1), "#c" \n\t"\ - "movq "#o"+24(%1), "#d" \n\t"\ - -#define STORE4(o, a, b, c, d)\ - "movq "#a", "#o"(%1) \n\t"\ - "movq "#b", "#o"+8(%1) \n\t"\ - "movq "#c", "#o"+16(%1) \n\t"\ - "movq "#d", "#o"+24(%1) \n\t"\ - /* FIXME: HSUM_* saturates at 64k, while an 8x8 hadamard or dct block can get up to * about 100k on extreme inputs. But that's very unlikely to occur in natural video, * and it's even more unlikely to not have any alternative mvs/modes with lower cost. */ @@ -1053,11 +1041,11 @@ static int hadamard8_diff_##cpu(void *s, uint8_t *src1, uint8_t *src2, int strid "movq %%mm7, 96(%1) \n\t"\ \ TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7)\ - STORE4(0 , %%mm0, %%mm3, %%mm7, %%mm2)\ + STORE4(8, 0(%1), %%mm0, %%mm3, %%mm7, %%mm2)\ \ "movq 96(%1), %%mm7 \n\t"\ TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0)\ - STORE4(64, %%mm4, %%mm7, %%mm0, %%mm6)\ + STORE4(8, 64(%1), %%mm4, %%mm7, %%mm0, %%mm6)\ \ : "=r" (sum)\ : "r"(temp)\ @@ -1071,7 +1059,7 @@ static int hadamard8_diff_##cpu(void *s, uint8_t *src1, uint8_t *src2, int strid "movq %%mm7, 96(%1) \n\t"\ \ TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7)\ - STORE4(32, %%mm0, %%mm3, %%mm7, %%mm2)\ + STORE4(8, 32(%1), %%mm0, %%mm3, %%mm7, %%mm2)\ \ "movq 96(%1), %%mm7 \n\t"\ TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0)\ @@ -1079,7 +1067,7 @@ static int hadamard8_diff_##cpu(void *s, uint8_t *src1, uint8_t *src2, int strid "movq %%mm6, %%mm7 \n\t"\ "movq %%mm0, %%mm6 \n\t"\ \ - LOAD4(64, %%mm0, %%mm1, %%mm2, %%mm3)\ + LOAD4(8, 64(%1), %%mm0, %%mm1, %%mm2, %%mm3)\ \ HADAMARD48\ "movq %%mm7, 64(%1) \n\t"\ @@ -1095,8 +1083,8 @@ static int hadamard8_diff_##cpu(void *s, uint8_t *src1, uint8_t *src2, int strid "paddusw %%mm1, %%mm0 \n\t"\ "movq %%mm0, 64(%1) \n\t"\ \ - LOAD4(0 , %%mm0, %%mm1, %%mm2, %%mm3)\ - LOAD4(32, %%mm4, %%mm5, %%mm6, %%mm7)\ + LOAD4(8, 0(%1), %%mm0, %%mm1, %%mm2, %%mm3)\ + LOAD4(8, 32(%1), %%mm4, %%mm5, %%mm6, %%mm7)\ \ HADAMARD48\ "movq %%mm7, (%1) \n\t"\ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/fft_3dn2.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/fft_3dn2.c @@ -124,10 +124,9 @@ void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z) asm volatile("femms"); } -void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp) +static void imdct_3dn2(MDCTContext *s, const FFTSample *input, FFTSample *tmp) { - long n8, n4, n2, n; + long n4, n2, n; x86_reg k; const uint16_t *revtab = s->fft.revtab; const FFTSample *tcos = s->tcos; @@ -138,7 +137,6 @@ void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, n = 1 << s->nbits; n2 = n >> 1; n4 = n >> 2; - n8 = n >> 3; /* pre rotation */ in1 = input; @@ -182,6 +180,20 @@ void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, :"m"(tcos[k]), "m"(tsin[k]) ); } +} + +void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + x86_reg k; + long n8, n2, n; + FFTComplex *z = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n2 = n >> 1; + n8 = n >> 3; + + imdct_3dn2(s, input, tmp); k = n-8; asm volatile("movd %0, %%mm7" ::"r"(1<<31)); @@ -212,3 +224,40 @@ void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, asm volatile("femms"); } +void ff_imdct_half_3dn2(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + x86_reg j, k; + long n8, n4, n; + FFTComplex *z = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n4 = n >> 2; + n8 = n >> 3; + + imdct_3dn2(s, input, tmp); + + j = -n; + k = n-8; + asm volatile("movd %0, %%mm7" ::"r"(1<<31)); + asm volatile( + "1: \n\t" + "movq (%3,%1), %%mm0 \n\t" // z[n8+k] + "pswapd (%3,%0), %%mm1 \n\t" // z[n8-1-k] + "movq %%mm0, %%mm2 \n\t" + "punpckldq %%mm1, %%mm0 \n\t" + "punpckhdq %%mm2, %%mm1 \n\t" + "pxor %%mm7, %%mm0 \n\t" + "pxor %%mm7, %%mm1 \n\t" + "movq %%mm0, (%2,%1) \n\t" // output[n4+2*k] = { -z[n8+k].re, z[n8-1-k].im } + "movq %%mm1, (%2,%0) \n\t" // output[n4-2-2*k] = { -z[n8-1-k].re, z[n8+k].im } + "sub $8, %1 \n\t" + "add $8, %0 \n\t" + "jl 1b \n\t" + :"+r"(j), "+r"(k) + :"r"(output+n4), "r"(z+n8) + :"memory" + ); + asm volatile("femms"); +} + diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/fft_sse.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/fft_sse.c @@ -142,11 +142,10 @@ void ff_fft_calc_sse(FFTContext *s, FFTComplex *z) } while (nblocks != 0); } -void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp) +static void imdct_sse(MDCTContext *s, const FFTSample *input, FFTSample *tmp) { x86_reg k; - long n8, n4, n2, n; + long n4, n2, n; const uint16_t *revtab = s->fft.revtab; const FFTSample *tcos = s->tcos; const FFTSample *tsin = s->tsin; @@ -156,7 +155,6 @@ void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, n = 1 << s->nbits; n2 = n >> 1; n4 = n >> 2; - n8 = n >> 3; #ifdef ARCH_X86_64 asm volatile ("movaps %0, %%xmm8\n\t"::"m"(*p1m1p1m1)); @@ -260,6 +258,20 @@ void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, #endif ); } +} + +void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + x86_reg k; + long n8, n2, n; + FFTComplex *z = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n2 = n >> 1; + n8 = n >> 3; + + imdct_sse(s, input, tmp); /* Mnemonics: @@ -301,3 +313,41 @@ void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, ); } +void ff_imdct_half_sse(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + x86_reg j, k; + long n8, n4, n; + FFTComplex *z = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n4 = n >> 2; + n8 = n >> 3; + + imdct_sse(s, input, tmp); + + j = -n; + k = n-16; + asm volatile("movaps %0, %%xmm7 \n\t"::"m"(*m1m1m1m1)); + asm volatile( + "1: \n\t" + "movaps (%3,%1), %%xmm0 \n\t" + "movaps (%3,%0), %%xmm1 \n\t" + "xorps %%xmm7, %%xmm0 \n\t" + "movaps %%xmm0, %%xmm2 \n\t" + "shufps $141,%%xmm1, %%xmm0 \n\t" + "shufps $216,%%xmm1, %%xmm2 \n\t" + "shufps $54, %%xmm0, %%xmm0 \n\t" + "shufps $156,%%xmm2, %%xmm2 \n\t" + "xorps %%xmm7, %%xmm0 \n\t" + "movaps %%xmm2, (%2,%1) \n\t" + "movaps %%xmm0, (%2,%0) \n\t" + "sub $16, %1 \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + :"+r"(j), "+r"(k) + :"r"(output+n4), "r"(z+n8) + :"memory" + ); +} + diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/flacdsp_mmx.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/flacdsp_mmx.c @@ -29,32 +29,32 @@ static void apply_welch_window_sse2(const int32_t *data, int len, double *w_data x86_reg i = -n2*sizeof(int32_t); x86_reg j = n2*sizeof(int32_t); asm volatile( - "movsd %0, %%xmm7 \n\t" - "movapd %1, %%xmm6 \n\t" - "movapd %2, %%xmm5 \n\t" - "movlhps %%xmm7, %%xmm7 \n\t" - "subpd %%xmm5, %%xmm7 \n\t" - "addsd %%xmm6, %%xmm7 \n\t" - ::"m"(c), "m"(*ff_pd_1), "m"(*ff_pd_2) + "movsd %0, %%xmm7 \n\t" + "movapd "MANGLE(ff_pd_1)", %%xmm6 \n\t" + "movapd "MANGLE(ff_pd_2)", %%xmm5 \n\t" + "movlhps %%xmm7, %%xmm7 \n\t" + "subpd %%xmm5, %%xmm7 \n\t" + "addsd %%xmm6, %%xmm7 \n\t" + ::"m"(c) ); #define WELCH(MOVPD, offset)\ asm volatile(\ - "1: \n\t"\ - "movapd %%xmm7, %%xmm1 \n\t"\ - "mulpd %%xmm1, %%xmm1 \n\t"\ - "movapd %%xmm6, %%xmm0 \n\t"\ - "subpd %%xmm1, %%xmm0 \n\t"\ - "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ - "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ - "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ - "mulpd %%xmm0, %%xmm2 \n\t"\ - "mulpd %%xmm1, %%xmm3 \n\t"\ - "movapd %%xmm2, (%2,%0,2) \n\t"\ + "1: \n\t"\ + "movapd %%xmm7, %%xmm1 \n\t"\ + "mulpd %%xmm1, %%xmm1 \n\t"\ + "movapd %%xmm6, %%xmm0 \n\t"\ + "subpd %%xmm1, %%xmm0 \n\t"\ + "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ + "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ + "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ + "mulpd %%xmm0, %%xmm2 \n\t"\ + "mulpd %%xmm1, %%xmm3 \n\t"\ + "movapd %%xmm2, (%2,%0,2) \n\t"\ MOVPD" %%xmm3, "#offset"*8(%2,%1,2) \n\t"\ - "subpd %%xmm5, %%xmm7 \n\t"\ - "sub $8, %1 \n\t"\ - "add $8, %0 \n\t"\ - "jl 1b \n\t"\ + "subpd %%xmm5, %%xmm7 \n\t"\ + "sub $8, %1 \n\t"\ + "add $8, %0 \n\t"\ + "jl 1b \n\t"\ :"+&r"(i), "+&r"(j)\ :"r"(w_data+n2), "r"(data+n2)\ ); @@ -85,54 +85,54 @@ void ff_flac_compute_autocorr_sse2(const int32_t *data, int len, int lag, x86_reg i = -len*sizeof(double); if(j == lag-2) { asm volatile( - "movsd %6, %%xmm0 \n\t" - "movsd %6, %%xmm1 \n\t" - "movsd %6, %%xmm2 \n\t" - "1: \n\t" - "movapd (%4,%0), %%xmm3 \n\t" - "movupd -8(%5,%0), %%xmm4 \n\t" - "movapd (%5,%0), %%xmm5 \n\t" - "mulpd %%xmm3, %%xmm4 \n\t" - "mulpd %%xmm3, %%xmm5 \n\t" - "mulpd -16(%5,%0), %%xmm3 \n\t" - "addpd %%xmm4, %%xmm1 \n\t" - "addpd %%xmm5, %%xmm0 \n\t" - "addpd %%xmm3, %%xmm2 \n\t" - "add $16, %0 \n\t" - "jl 1b \n\t" - "movhlps %%xmm0, %%xmm3 \n\t" - "movhlps %%xmm1, %%xmm4 \n\t" - "movhlps %%xmm2, %%xmm5 \n\t" - "addsd %%xmm3, %%xmm0 \n\t" - "addsd %%xmm4, %%xmm1 \n\t" - "addsd %%xmm5, %%xmm2 \n\t" - "movsd %%xmm0, %1 \n\t" - "movsd %%xmm1, %2 \n\t" - "movsd %%xmm2, %3 \n\t" + "movsd "MANGLE(ff_pd_1)", %%xmm0 \n\t" + "movsd "MANGLE(ff_pd_1)", %%xmm1 \n\t" + "movsd "MANGLE(ff_pd_1)", %%xmm2 \n\t" + "1: \n\t" + "movapd (%4,%0), %%xmm3 \n\t" + "movupd -8(%5,%0), %%xmm4 \n\t" + "movapd (%5,%0), %%xmm5 \n\t" + "mulpd %%xmm3, %%xmm4 \n\t" + "mulpd %%xmm3, %%xmm5 \n\t" + "mulpd -16(%5,%0), %%xmm3 \n\t" + "addpd %%xmm4, %%xmm1 \n\t" + "addpd %%xmm5, %%xmm0 \n\t" + "addpd %%xmm3, %%xmm2 \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + "movhlps %%xmm0, %%xmm3 \n\t" + "movhlps %%xmm1, %%xmm4 \n\t" + "movhlps %%xmm2, %%xmm5 \n\t" + "addsd %%xmm3, %%xmm0 \n\t" + "addsd %%xmm4, %%xmm1 \n\t" + "addsd %%xmm5, %%xmm2 \n\t" + "movsd %%xmm0, %1 \n\t" + "movsd %%xmm1, %2 \n\t" + "movsd %%xmm2, %3 \n\t" :"+&r"(i), "=m"(autoc[j]), "=m"(autoc[j+1]), "=m"(autoc[j+2]) - :"r"(data1+len), "r"(data1+len-j), "m"(*ff_pd_1) + :"r"(data1+len), "r"(data1+len-j) ); } else { asm volatile( - "movsd %5, %%xmm0 \n\t" - "movsd %5, %%xmm1 \n\t" - "1: \n\t" - "movapd (%3,%0), %%xmm3 \n\t" - "movupd -8(%4,%0), %%xmm4 \n\t" - "mulpd %%xmm3, %%xmm4 \n\t" - "mulpd (%4,%0), %%xmm3 \n\t" - "addpd %%xmm4, %%xmm1 \n\t" - "addpd %%xmm3, %%xmm0 \n\t" - "add $16, %0 \n\t" - "jl 1b \n\t" - "movhlps %%xmm0, %%xmm3 \n\t" - "movhlps %%xmm1, %%xmm4 \n\t" - "addsd %%xmm3, %%xmm0 \n\t" - "addsd %%xmm4, %%xmm1 \n\t" - "movsd %%xmm0, %1 \n\t" - "movsd %%xmm1, %2 \n\t" + "movsd "MANGLE(ff_pd_1)", %%xmm0 \n\t" + "movsd "MANGLE(ff_pd_1)", %%xmm1 \n\t" + "1: \n\t" + "movapd (%3,%0), %%xmm3 \n\t" + "movupd -8(%4,%0), %%xmm4 \n\t" + "mulpd %%xmm3, %%xmm4 \n\t" + "mulpd (%4,%0), %%xmm3 \n\t" + "addpd %%xmm4, %%xmm1 \n\t" + "addpd %%xmm3, %%xmm0 \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + "movhlps %%xmm0, %%xmm3 \n\t" + "movhlps %%xmm1, %%xmm4 \n\t" + "addsd %%xmm3, %%xmm0 \n\t" + "addsd %%xmm4, %%xmm1 \n\t" + "movsd %%xmm0, %1 \n\t" + "movsd %%xmm1, %2 \n\t" :"+&r"(i), "=m"(autoc[j]), "=m"(autoc[j+1]) - :"r"(data1+len), "r"(data1+len-j), "m"(*ff_pd_1) + :"r"(data1+len), "r"(data1+len-j) ); } } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/h264dsp_mmx.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/h264dsp_mmx.c @@ -20,6 +20,9 @@ #include "dsputil_mmx.h" +DECLARE_ALIGNED_8 (static const uint64_t, ff_pb_3_1 ) = 0x0103010301030103ULL; +DECLARE_ALIGNED_8 (static const uint64_t, ff_pb_7_3 ) = 0x0307030703070307ULL; + /***********************************/ /* IDCT */ @@ -623,7 +626,7 @@ static void h264_h_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int a } static void h264_loop_filter_strength_mmx2( int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], - int bidir, int edges, int step, int mask_mv0, int mask_mv1 ) { + int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field ) { int dir; asm volatile( "pxor %%mm7, %%mm7 \n\t" @@ -632,6 +635,13 @@ static void h264_loop_filter_strength_mmx2( int16_t bS[2][4][4], uint8_t nnz[40] "movq %2, %%mm4 \n\t" ::"m"(ff_pb_1), "m"(ff_pb_3), "m"(ff_pb_7) ); + if(field) + asm volatile( + "movq %0, %%mm5 \n\t" + "movq %1, %%mm4 \n\t" + ::"m"(ff_pb_3_1), "m"(ff_pb_7_3) + ); + // could do a special case for dir==0 && edges==1, but it only reduces the // average filter time by 1.2% for( dir=1; dir>=0; dir-- ) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/idct_sse2_xvid.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/i386/idct_sse2_xvid.c @@ -39,6 +39,7 @@ */ #include "libavcodec/dsputil.h" +#include "libavcodec/i386/idct_xvid.h" /*! * @file idct_sse2_xvid.c diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/imc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/imc.c @@ -79,7 +79,6 @@ typedef struct { int codewords[COEFFS]; ///< raw codewords read from bitstream float sqrt_tab[30]; GetBitContext gb; - VLC huffman_vlc[4][4]; int decoder_reset; float one_div_log2; @@ -89,6 +88,15 @@ typedef struct { DECLARE_ALIGNED_16(float, out_samples[COEFFS]); } IMCContext; +static VLC huffman_vlc[4][4]; + +#define VLC_TABLES_SIZE 9512 + +static const int vlc_offsets[17] = { + 0, 640, 1156, 1732, 2308, 2852, 3396, 3924, + 4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE}; + +static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2]; static av_cold int imc_decode_init(AVCodecContext * avctx) { @@ -102,8 +110,9 @@ static av_cold int imc_decode_init(AVCodecContext * avctx) q->old_floor[i] = 1.0; /* Build mdct window, a simple sine window normalized with sqrt(2) */ + ff_sine_window_init(q->mdct_sine_window, COEFFS); for(i = 0; i < COEFFS; i++) - q->mdct_sine_window[i] = sin((i + 0.5) / 512.0 * M_PI) * sqrt(2.0); + q->mdct_sine_window[i] *= sqrt(2.0); for(i = 0; i < COEFFS/2; i++){ q->post_cos[i] = cos(i / 256.0 * M_PI); q->post_sin[i] = sin(i / 256.0 * M_PI); @@ -134,9 +143,11 @@ static av_cold int imc_decode_init(AVCodecContext * avctx) /* initialize the VLC tables */ for(i = 0; i < 4 ; i++) { for(j = 0; j < 4; j++) { - init_vlc (&q->huffman_vlc[i][j], 9, imc_huffman_sizes[i], + huffman_vlc[i][j].table = vlc_tables[vlc_offsets[i * 4 + j]]; + huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j]; + init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i], imc_huffman_lens[i][j], 1, 1, - imc_huffman_bits[i][j], 2, 2, 1); + imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC); } } q->one_div_log2 = 1/log(2); @@ -209,10 +220,10 @@ static void imc_read_level_coeffs(IMCContext* q, int stream_format_code, int* le int s; s = stream_format_code >> 1; - hufftab[0] = &q->huffman_vlc[s][0]; - hufftab[1] = &q->huffman_vlc[s][1]; - hufftab[2] = &q->huffman_vlc[s][2]; - hufftab[3] = &q->huffman_vlc[s][3]; + hufftab[0] = &huffman_vlc[s][0]; + hufftab[1] = &huffman_vlc[s][1]; + hufftab[2] = &huffman_vlc[s][2]; + hufftab[3] = &huffman_vlc[s][3]; cb_sel = imc_cb_select[s]; if(stream_format_code & 4) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/imcdata.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/imcdata.h @@ -94,7 +94,7 @@ static const float imc_exp_tab[32] = { 1.778280e02, 3.162278e02, 5.623413e02, 1.000000e03, 1.778280e03, 3.162278e03, 5.623413e03, 1.000000e04 }; -static const float *imc_exp_tab2 = imc_exp_tab + 8; +static const float * const imc_exp_tab2 = imc_exp_tab + 8; static const uint8_t imc_cb_select[4][32] = { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/imgconvert.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/imgconvert.c @@ -896,8 +896,8 @@ void av_picture_copy(AVPicture *dst, const AVPicture *src, for(i = 0; i < pf->nb_channels; i++) { int w, h; int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i); - if (bwidth < 0) - continue; /* unknown pixel type, ignore */ + if (bwidth < 0) + continue; /* unknown pixel type, ignore */ w = width; h = height; if (i == 1 || i == 2) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/jpegls.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/jpegls.c @@ -27,13 +27,6 @@ #include "jpegls.h" -const uint8_t ff_log2_run[32]={ - 0, 0, 0, 0, 1, 1, 1, 1, - 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 9,10,11,12,13,14,15 -}; - void ff_jpegls_init_state(JLSState *state){ int i; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libdirac_libschro.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libdirac_libschro.c @@ -70,6 +70,7 @@ unsigned int ff_dirac_schro_get_video_format_idx (AVCodecContext *avccontext) void ff_dirac_schro_queue_init (FfmpegDiracSchroQueue *queue) { queue->p_head = queue->p_tail = NULL; + queue->size = 0; } void ff_dirac_schro_queue_free (FfmpegDiracSchroQueue *queue, @@ -96,6 +97,7 @@ int ff_dirac_schro_queue_push_back (FfmpegDiracSchroQueue *queue, void *p_data) queue->p_tail->next = p_new; queue->p_tail = p_new; + ++queue->size; return 0; } @@ -106,6 +108,7 @@ void *ff_dirac_schro_queue_pop (FfmpegDiracSchroQueue *queue) if (top != NULL) { void *data = top->data; queue->p_head = queue->p_head->next; + --queue->size; av_freep (&top); return data; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libdirac_libschro.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libdirac_libschro.h @@ -80,6 +80,8 @@ typedef struct FfmpegDiracSchroQueue FfmpegDiracSchroQueueElement *p_head; /** Pointer to tail of queue */ FfmpegDiracSchroQueueElement *p_tail; + /** Queue size*/ + int size; } FfmpegDiracSchroQueue; /** diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libdiracenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libdiracenc.c @@ -55,6 +55,12 @@ typedef struct FfmpegDiracEncoderParams /** input frame buffer */ unsigned char *p_in_frame_buf; + /** buffer to store encoder output before writing it to the frame queue */ + unsigned char *enc_buf; + + /** size of encoder buffer */ + int enc_buf_size; + /** queue storing encoded frames */ FfmpegDiracSchroQueue enc_frame_queue; @@ -236,6 +242,7 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL; int go = 1; + int last_frame_in_sequence = 0; if (data == NULL) { /* push end of sequence if not already signalled */ @@ -278,18 +285,39 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, case ENC_STATE_AVAIL: case ENC_STATE_EOS: assert (p_dirac_params->p_encoder->enc_buf.size > 0); - /* create output frame */ - p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); - /* set output data */ - p_frame_output->p_encbuf = - av_malloc(p_dirac_params->p_encoder->enc_buf.size); - memcpy(p_frame_output->p_encbuf, + /* All non-frame data is prepended to actual frame data to + * be able to set the pts correctly. So we don't write data + * to the frame output queue until we actually have a frame + */ + + p_dirac_params->enc_buf = av_realloc ( + p_dirac_params->enc_buf, + p_dirac_params->enc_buf_size + + p_dirac_params->p_encoder->enc_buf.size + ); + memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size, p_dirac_params->p_encoder->enc_buf.buffer, p_dirac_params->p_encoder->enc_buf.size); - p_frame_output->size = p_dirac_params->p_encoder->enc_buf.size; + p_dirac_params->enc_buf_size += + p_dirac_params->p_encoder->enc_buf.size; + + if (state == ENC_STATE_EOS) { + p_dirac_params->eos_pulled = 1; + go = 0; + } + + /* If non-frame data, don't output it until it we get an + * encoded frame back from the encoder. */ + if (p_dirac_params->p_encoder->enc_pparams.pnum == -1) + break; + /* create output frame */ + p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); + /* set output data */ + p_frame_output->size = p_dirac_params->enc_buf_size; + p_frame_output->p_encbuf = p_dirac_params->enc_buf; p_frame_output->frame_num = p_dirac_params->p_encoder->enc_pparams.pnum; @@ -300,10 +328,8 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue, p_frame_output); - if (state == ENC_STATE_EOS) { - p_dirac_params->eos_pulled = 1; - go = 0; - } + p_dirac_params->enc_buf_size = 0; + p_dirac_params->enc_buf = NULL; break; case ENC_STATE_BUFFER: @@ -322,6 +348,11 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, } /* copy 'next' frame in queue */ + + if (p_dirac_params->enc_frame_queue.size == 1 && + p_dirac_params->eos_pulled) + last_frame_in_sequence = 1; + p_next_output_frame = ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue); @@ -336,6 +367,17 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, avccontext->coded_frame->pts = p_next_output_frame->frame_num; enc_size = p_next_output_frame->size; + /* Append the end of sequence information to the last frame in the + * sequence. */ + if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0) + { + memcpy (frame + enc_size, p_dirac_params->enc_buf, + p_dirac_params->enc_buf_size); + enc_size += p_dirac_params->enc_buf_size; + av_freep (&p_dirac_params->enc_buf); + p_dirac_params->enc_buf_size = 0; + } + /* free frame */ DiracFreeFrame(p_next_output_frame); @@ -353,6 +395,10 @@ static int libdirac_encode_close(AVCodecContext *avccontext) ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue, DiracFreeFrame); + /* free the encoder buffer */ + if (p_dirac_params->enc_buf_size) + av_freep(&p_dirac_params->enc_buf); + /* free the input frame buffer */ av_freep(&p_dirac_params->p_in_frame_buf); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libfaad.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libfaad.c @@ -196,7 +196,8 @@ static int faac_decode_frame(AVCodecContext *avctx, s->faacDecGetErrorMessage(frame_info.error)); return -1; } - + if (!avctx->frame_size) + avctx->frame_size = frame_info.samples/avctx->channels; frame_info.samples *= s->sample_size; memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libschroedingerdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libschroedingerdec.c @@ -64,6 +64,60 @@ typedef struct FfmpegSchroDecoderParams AVPicture dec_pic; } FfmpegSchroDecoderParams; +typedef struct FfmpegSchroParseUnitContext +{ + const uint8_t *buf; + int buf_size; +} FfmpegSchroParseUnitContext; + + +static void libschroedinger_decode_buffer_free (SchroBuffer *schro_buf, + void *priv); + +static void FfmpegSchroParseContextInit (FfmpegSchroParseUnitContext *parse_ctx, + const uint8_t *buf, int buf_size) +{ + parse_ctx->buf = buf; + parse_ctx->buf_size = buf_size; +} + +static SchroBuffer* FfmpegFindNextSchroParseUnit (FfmpegSchroParseUnitContext *parse_ctx) +{ + SchroBuffer *enc_buf = NULL; + int next_pu_offset = 0; + unsigned char *in_buf; + + if (parse_ctx->buf_size < 13 || + parse_ctx->buf[0] != 'B' || + parse_ctx->buf[1] != 'B' || + parse_ctx->buf[2] != 'C' || + parse_ctx->buf[3] != 'D') + return NULL; + + next_pu_offset = (parse_ctx->buf[5] << 24) + + (parse_ctx->buf[6] << 16) + + (parse_ctx->buf[7] << 8) + + parse_ctx->buf[8]; + + if (next_pu_offset == 0 && + SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4])) + next_pu_offset = 13; + + if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset) + return NULL; + + in_buf = av_malloc(next_pu_offset); + memcpy (in_buf, parse_ctx->buf, next_pu_offset); + enc_buf = schro_buffer_new_with_data (in_buf, next_pu_offset); + enc_buf->free = libschroedinger_decode_buffer_free; + enc_buf->priv = in_buf; + + parse_ctx->buf += next_pu_offset; + parse_ctx->buf_size -= next_pu_offset; + + return enc_buf; +} + /** * Returns FFmpeg chroma format. */ @@ -164,26 +218,30 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, SchroFrame* frame; int state; int go = 1; + int outer = 1; + FfmpegSchroParseUnitContext parse_ctx; *data_size = 0; - if (buf_size>0) { - unsigned char *in_buf = av_malloc(buf_size); - memcpy (in_buf, buf, buf_size); - enc_buf = schro_buffer_new_with_data (in_buf, buf_size); - enc_buf->free = libschroedinger_decode_buffer_free; - enc_buf->priv = in_buf; - /* Push buffer into decoder. */ - state = schro_decoder_push (decoder, enc_buf); - if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT) - libschroedinger_handle_first_access_unit(avccontext); - } else { + FfmpegSchroParseContextInit (&parse_ctx, buf, buf_size); + if (buf_size == 0) { if (!p_schro_params->eos_signalled) { state = schro_decoder_push_end_of_stream(decoder); p_schro_params->eos_signalled = 1; } } + /* Loop through all the individual parse units in the input buffer */ + do { + if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) { + /* Push buffer into decoder. */ + state = schro_decoder_push (decoder, enc_buf); + if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT) + libschroedinger_handle_first_access_unit(avccontext); + go = 1; + } + else + outer = 0; format = p_schro_params->format; while (go) { @@ -224,6 +282,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, go = 0; p_schro_params->eos_pulled = 1; schro_decoder_reset (decoder); + outer = 0; break; case SCHRO_DECODER_ERROR: @@ -231,6 +290,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, break; } } + } while(outer); /* Grab next frame to be returned from the top of the queue. */ frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libschroedingerenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/libschroedingerenc.c @@ -57,6 +57,12 @@ typedef struct FfmpegSchroEncoderParams /** Schroedinger encoder handle*/ SchroEncoder* encoder; + /** buffer to store encoder output before writing it to the frame queue*/ + unsigned char *enc_buf; + + /** Size of encoder buffer*/ + int enc_buf_size; + /** queue storing encoded frames */ FfmpegDiracSchroQueue enc_frame_queue; @@ -255,6 +261,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, SchroBuffer *enc_buf; int presentation_frame; int parse_code; + int last_frame_in_sequence = 0; if(data == NULL) { /* Push end of sequence if not already signalled. */ @@ -285,15 +292,37 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, &presentation_frame); assert (enc_buf->length > 0); assert (enc_buf->length <= buf_size); + parse_code = enc_buf->data[4]; + + /* All non-frame data is prepended to actual frame data to + * be able to set the pts correctly. So we don't write data + * to the frame output queue until we actually have a frame + */ + p_schro_params->enc_buf = av_realloc ( + p_schro_params->enc_buf, + p_schro_params->enc_buf_size + enc_buf->length + ); + + memcpy(p_schro_params->enc_buf+p_schro_params->enc_buf_size, + enc_buf->data, enc_buf->length); + p_schro_params->enc_buf_size += enc_buf->length; + + + if (state == SCHRO_STATE_END_OF_STREAM) { + p_schro_params->eos_pulled = 1; + go = 0; + } + + if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { + schro_buffer_unref (enc_buf); + break; + } /* Create output frame. */ p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); /* Set output data. */ - p_frame_output->size = enc_buf->length; - p_frame_output->p_encbuf = av_malloc(enc_buf->length); - memcpy(p_frame_output->p_encbuf, enc_buf->data, enc_buf->length); - - parse_code = enc_buf->data[4]; + p_frame_output->size = p_schro_params->enc_buf_size; + p_frame_output->p_encbuf = p_schro_params->enc_buf; if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) { p_frame_output->key_frame = 1; @@ -301,23 +330,18 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, /* Parse the coded frame number from the bitstream. Bytes 14 * through 17 represesent the frame number. */ - if (SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) - { - assert (enc_buf->length >= 17); p_frame_output->frame_num = (enc_buf->data[13] << 24) + (enc_buf->data[14] << 16) + (enc_buf->data[15] << 8) + enc_buf->data[16]; - } ff_dirac_schro_queue_push_back (&p_schro_params->enc_frame_queue, p_frame_output); + p_schro_params->enc_buf_size = 0; + p_schro_params->enc_buf = NULL; + schro_buffer_unref (enc_buf); - if (state == SCHRO_STATE_END_OF_STREAM) { - p_schro_params->eos_pulled = 1; - go = 0; - } break; case SCHRO_STATE_NEED_FRAME: @@ -334,6 +358,11 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, } /* Copy 'next' frame in queue. */ + + if (p_schro_params->enc_frame_queue.size == 1 && + p_schro_params->eos_pulled) + last_frame_in_sequence = 1; + p_frame_output = ff_dirac_schro_queue_pop (&p_schro_params->enc_frame_queue); @@ -348,6 +377,17 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, avccontext->coded_frame->pts = p_frame_output->frame_num; enc_size = p_frame_output->size; + /* Append the end of sequence information to the last frame in the + * sequence. */ + if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) + { + memcpy (frame + enc_size, p_schro_params->enc_buf, + p_schro_params->enc_buf_size); + enc_size += p_schro_params->enc_buf_size; + av_freep (&p_schro_params->enc_buf); + p_schro_params->enc_buf_size = 0; + } + /* free frame */ SchroedingerFreeFrame (p_frame_output); @@ -367,6 +407,11 @@ static int libschroedinger_encode_close(AVCodecContext *avccontext) ff_dirac_schro_queue_free (&p_schro_params->enc_frame_queue, SchroedingerFreeFrame); + + /* Free the encoder buffer. */ + if (p_schro_params->enc_buf_size) + av_freep(&p_schro_params->enc_buf); + /* Free the video format structure. */ av_freep(&p_schro_params->format); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/lsp.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/lsp.h @@ -37,7 +37,7 @@ * \param lsfq_max maximum allowed LSF value * \param lp_order LP filter order */ -void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsqf_min, int lsfq_max, int lp_order); +void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order); /** * \brief Convert LSF to LSP diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/lzw.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/lzw.c @@ -131,7 +131,7 @@ int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, { struct LZWState *s = (struct LZWState *)p; - if(csize < 1 || csize > LZW_MAXBITS) + if(csize < 1 || csize >= LZW_MAXBITS) return -1; /* read buffer */ s->pbuf = buf; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mathops.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mathops.h @@ -61,6 +61,14 @@ static av_always_inline int MULH(int a, int b){ # define MUL64(a,b) ((int64_t)(a) * (int64_t)(b)) #endif +#ifndef MAC64 +# define MAC64(d, a, b) ((d) += MUL64(a, b)) +#endif + +#ifndef MLS64 +# define MLS64(d, a, b) ((d) -= MUL64(a, b)) +#endif + /* signed 16x16 -> 32 multiply add accumulate */ #ifndef MAC16 # define MAC16(rt, ra, rb) rt += (ra) * (rb) @@ -71,5 +79,9 @@ static av_always_inline int MULH(int a, int b){ # define MUL16(ra, rb) ((ra) * (rb)) #endif +#ifndef MLS16 +# define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb)) +#endif + #endif /* FFMPEG_MATHOPS_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mdct.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mdct.c @@ -48,6 +48,13 @@ void ff_kbd_window_init(float *window, float alpha, int n) window[i] = sqrt(local_window[i] / sum); } +// Generate a sine window. +void ff_sine_window_init(float *window, int n) { + int i; + for(i = 0; i < n; i++) + window[i] = sin((i + 0.5) / (2 * n) * M_PI); +} + /** * init MDCT or IMDCT computation. */ @@ -93,16 +100,9 @@ int ff_mdct_init(MDCTContext *s, int nbits, int inverse) (pim) = _are * _bim + _aim * _bre;\ } -/** - * Compute inverse MDCT of size N = 2^nbits - * @param output N samples - * @param input N/2 samples - * @param tmp N/2 samples - */ -void ff_imdct_calc(MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp) +static void imdct_c(MDCTContext *s, const FFTSample *input, FFTSample *tmp) { - int k, n8, n4, n2, n, j; + int k, n4, n2, n, j; const uint16_t *revtab = s->fft.revtab; const FFTSample *tcos = s->tcos; const FFTSample *tsin = s->tsin; @@ -112,7 +112,6 @@ void ff_imdct_calc(MDCTContext *s, FFTSample *output, n = 1 << s->nbits; n2 = n >> 1; n4 = n >> 2; - n8 = n >> 3; /* pre rotation */ in1 = input; @@ -130,6 +129,25 @@ void ff_imdct_calc(MDCTContext *s, FFTSample *output, for(k = 0; k < n4; k++) { CMUL(z[k].re, z[k].im, z[k].re, z[k].im, tcos[k], tsin[k]); } +} + +/** + * Compute inverse MDCT of size N = 2^nbits + * @param output N samples + * @param input N/2 samples + * @param tmp N/2 samples + */ +void ff_imdct_calc(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + int k, n8, n2, n; + FFTComplex *z = (FFTComplex *)tmp; + n = 1 << s->nbits; + n2 = n >> 1; + n8 = n >> 3; + + imdct_c(s, input, tmp); + for(k = 0; k < n8; k++) { output[2*k] = -z[n8 + k].im; output[n2-1-2*k] = z[n8 + k].im; @@ -146,6 +164,32 @@ void ff_imdct_calc(MDCTContext *s, FFTSample *output, } /** + * Compute the middle half of the inverse MDCT of size N = 2^nbits, + * thus excluding the parts that can be derived by symmetry + * @param output N/2 samples + * @param input N/2 samples + * @param tmp N/2 samples + */ +void ff_imdct_half(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + int k, n8, n4, n; + FFTComplex *z = (FFTComplex *)tmp; + n = 1 << s->nbits; + n4 = n >> 2; + n8 = n >> 3; + + imdct_c(s, input, tmp); + + for(k = 0; k < n8; k++) { + output[n4-1-2*k] = z[n8+k].im; + output[n4-1-2*k-1] = -z[n8-k-1].re; + output[n4 + 2*k] = -z[n8+k].re; + output[n4 + 2*k+1] = z[n8-k-1].im; + } +} + +/** * Compute MDCT of size N = 2^nbits * @param input N samples * @param out N/2 samples diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mdec.c @@ -31,14 +31,10 @@ #include "dsputil.h" #include "mpegvideo.h" -//#undef NDEBUG -//#include <assert.h> - typedef struct MDECContext{ AVCodecContext *avctx; DSPContext dsp; AVFrame picture; - PutBitContext pb; GetBitContext gb; ScanTable scantable; int version; @@ -91,7 +87,6 @@ static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n) i += run; j = scantable[i]; level= (level*qscale*quant_matrix[j])>>3; -// level= (level-1)|1; level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1); LAST_SKIP_BITS(re, &a->gb, 1); } else { @@ -162,7 +157,7 @@ static int decode_frame(AVCodecContext *avctx, { MDECContext * const a = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&a->picture; + AVFrame * const p= &a->picture; int i; if(p->data[0]) @@ -193,8 +188,6 @@ static int decode_frame(AVCodecContext *avctx, a->last_dc[1]= a->last_dc[2]= 128; -// printf("qscale:%d (0x%X), version:%d (0x%X)\n", a->qscale, a->qscale, a->version, a->version); - for(a->mb_x=0; a->mb_x<a->mb_width; a->mb_x++){ for(a->mb_y=0; a->mb_y<a->mb_height; a->mb_y++){ if( decode_mb(a, a->block) <0) @@ -204,14 +197,12 @@ static int decode_frame(AVCodecContext *avctx, } } -// p->quality= (32 + a->inv_qscale/2)/a->inv_qscale; -// memset(p->qscale_table, p->quality, p->qstride*a->mb_height); + p->quality= a->qscale * FF_QP2LAMBDA; + memset(p->qscale_table, a->qscale, p->qstride*a->mb_height); - *picture= *(AVFrame*)&a->picture; + *picture = a->picture; *data_size = sizeof(AVPicture); - emms_c(); - return (get_bits_count(&a->gb)+31)/32*4; } @@ -223,23 +214,18 @@ static av_cold void mdec_common_init(AVCodecContext *avctx){ a->mb_width = (avctx->coded_width + 15) / 16; a->mb_height = (avctx->coded_height + 15) / 16; - avctx->coded_frame= (AVFrame*)&a->picture; + avctx->coded_frame= &a->picture; a->avctx= avctx; } static av_cold int decode_init(AVCodecContext *avctx){ MDECContext * const a = avctx->priv_data; - AVFrame *p= (AVFrame*)&a->picture; + AVFrame *p= &a->picture; mdec_common_init(avctx); init_vlcs(); ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_zigzag_direct); -/* - for(i=0; i<64; i++){ - int index= ff_zigzag_direct[i]; - a->intra_matrix[i]= 64*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; - } -*/ + p->qstride= a->mb_width; p->qscale_table= av_mallocz( p->qstride * a->mb_height); avctx->pix_fmt= PIX_FMT_YUV420P; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpeg.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpeg.c @@ -64,13 +64,11 @@ const unsigned char std_chrominance_quant_tbl[64] = { /* IMPORTANT: these are only valid for 8-bit data precision! */ const uint8_t ff_mjpeg_bits_dc_luminance[17] = { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t ff_mjpeg_val_dc_luminance[] = +const uint8_t ff_mjpeg_val_dc[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; const uint8_t ff_mjpeg_bits_dc_chrominance[17] = { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; -const uint8_t ff_mjpeg_val_dc_chrominance[] = -{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; const uint8_t ff_mjpeg_bits_ac_luminance[17] = { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpeg.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpeg.h @@ -138,10 +138,9 @@ static inline void put_marker(PutBitContext *p, int code) } extern const uint8_t ff_mjpeg_bits_dc_luminance[]; -extern const uint8_t ff_mjpeg_val_dc_luminance[]; +extern const uint8_t ff_mjpeg_val_dc[]; extern const uint8_t ff_mjpeg_bits_dc_chrominance[]; -extern const uint8_t ff_mjpeg_val_dc_chrominance[]; extern const uint8_t ff_mjpeg_bits_ac_luminance[]; extern const uint8_t ff_mjpeg_val_ac_luminance[]; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpegdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpegdec.c @@ -64,9 +64,9 @@ static int build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_tab static void build_basic_mjpeg_vlc(MJpegDecodeContext * s) { build_vlc(&s->vlcs[0][0], ff_mjpeg_bits_dc_luminance, - ff_mjpeg_val_dc_luminance, 12, 0, 0); + ff_mjpeg_val_dc, 12, 0, 0); build_vlc(&s->vlcs[0][1], ff_mjpeg_bits_dc_chrominance, - ff_mjpeg_val_dc_chrominance, 12, 0, 0); + ff_mjpeg_val_dc, 12, 0, 0); build_vlc(&s->vlcs[1][0], ff_mjpeg_bits_ac_luminance, ff_mjpeg_val_ac_luminance, 251, 0, 1); build_vlc(&s->vlcs[1][1], ff_mjpeg_bits_ac_chrominance, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpegenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mjpegenc.c @@ -59,11 +59,11 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, m->huff_code_dc_luminance, ff_mjpeg_bits_dc_luminance, - ff_mjpeg_val_dc_luminance); + ff_mjpeg_val_dc); ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, m->huff_code_dc_chrominance, ff_mjpeg_bits_dc_chrominance, - ff_mjpeg_val_dc_chrominance); + ff_mjpeg_val_dc); ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, m->huff_code_ac_luminance, ff_mjpeg_bits_ac_luminance, @@ -139,9 +139,9 @@ static void jpeg_table_header(MpegEncContext *s) put_bits(p, 16, 0); /* patched later */ size = 2; size += put_huffman_table(s, 0, 0, ff_mjpeg_bits_dc_luminance, - ff_mjpeg_val_dc_luminance); + ff_mjpeg_val_dc); size += put_huffman_table(s, 0, 1, ff_mjpeg_bits_dc_chrominance, - ff_mjpeg_val_dc_chrominance); + ff_mjpeg_val_dc); size += put_huffman_table(s, 1, 0, ff_mjpeg_bits_ac_luminance, ff_mjpeg_val_ac_luminance); @@ -369,7 +369,7 @@ void ff_mjpeg_encode_dc(MpegEncContext *s, int val, put_bits(&s->pb, huff_size[nbits], huff_code[nbits]); - put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); + put_sbits(&s->pb, nbits, mant); } } @@ -421,7 +421,7 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n) put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); - put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); + put_sbits(&s->pb, nbits, mant); run = 0; } } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mlp_parser.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mlp_parser.c @@ -24,6 +24,8 @@ * MLP parser */ +#include <stdint.h> + #include "libavutil/crc.h" #include "bitstream.h" #include "parser.h" @@ -65,8 +67,8 @@ static int truehd_channels(int chanmap) static int crc_init = 0; static AVCRC crc_2D[1024]; -/** MLP uses checksums that seem to be based on the standard CRC algorithm, - * but not (in implementation terms, the table lookup and XOR are reversed). +/** MLP uses checksums that seem to be based on the standard CRC algorithm, but + * are not (in implementation terms, the table lookup and XOR are reversed). * We can implement this behavior using a standard av_crc on all but the * last element, then XOR that with the last element. */ @@ -88,74 +90,73 @@ static uint16_t mlp_checksum16(const uint8_t *buf, unsigned int buf_size) /** Read a major sync info header - contains high level information about * the stream - sample rate, channel arrangement etc. Most of this * information is not actually necessary for decoding, only for playback. + * gb must be a freshly initialized GetBitContext with no bits read. */ -int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, const uint8_t *buf, - unsigned int buf_size) +int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) { - GetBitContext gb; int ratebits; uint16_t checksum; - if (buf_size < 28) { - av_log(log, AV_LOG_ERROR, "Packet too short, unable to read major sync\n"); + assert(get_bits_count(gb) == 0); + + if (gb->size_in_bits < 28 << 3) { + av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n"); return -1; } - checksum = mlp_checksum16(buf, 26); - if (checksum != AV_RL16(buf+26)) { - av_log(log, AV_LOG_ERROR, "Major sync info header checksum error\n"); + checksum = mlp_checksum16(gb->buffer, 26); + if (checksum != AV_RL16(gb->buffer+26)) { + av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n"); return -1; } - init_get_bits(&gb, buf, buf_size * 8); - - if (get_bits_long(&gb, 24) != 0xf8726f) /* Sync words */ + if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */ return -1; - mh->stream_type = get_bits(&gb, 8); + mh->stream_type = get_bits(gb, 8); if (mh->stream_type == 0xbb) { - mh->group1_bits = mlp_quants[get_bits(&gb, 4)]; - mh->group2_bits = mlp_quants[get_bits(&gb, 4)]; + mh->group1_bits = mlp_quants[get_bits(gb, 4)]; + mh->group2_bits = mlp_quants[get_bits(gb, 4)]; - ratebits = get_bits(&gb, 4); + ratebits = get_bits(gb, 4); mh->group1_samplerate = mlp_samplerate(ratebits); - mh->group2_samplerate = mlp_samplerate(get_bits(&gb, 4)); + mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4)); - skip_bits(&gb, 11); + skip_bits(gb, 11); - mh->channels_mlp = get_bits(&gb, 5); + mh->channels_mlp = get_bits(gb, 5); } else if (mh->stream_type == 0xba) { mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? mh->group2_bits = 0; - ratebits = get_bits(&gb, 4); + ratebits = get_bits(gb, 4); mh->group1_samplerate = mlp_samplerate(ratebits); mh->group2_samplerate = 0; - skip_bits(&gb, 8); + skip_bits(gb, 8); - mh->channels_thd_stream1 = get_bits(&gb, 5); + mh->channels_thd_stream1 = get_bits(gb, 5); - skip_bits(&gb, 2); + skip_bits(gb, 2); - mh->channels_thd_stream2 = get_bits(&gb, 13); + mh->channels_thd_stream2 = get_bits(gb, 13); } else return -1; mh->access_unit_size = 40 << (ratebits & 7); mh->access_unit_size_pow2 = 64 << (ratebits & 7); - skip_bits_long(&gb, 48); + skip_bits_long(gb, 48); - mh->is_vbr = get_bits1(&gb); + mh->is_vbr = get_bits1(gb); - mh->peak_bitrate = (get_bits(&gb, 15) * mh->group1_samplerate + 8) >> 4; + mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4; - mh->num_substreams = get_bits(&gb, 4); + mh->num_substreams = get_bits(gb, 4); - skip_bits_long(&gb, 4 + 11 * 8); + skip_bits_long(gb, 4 + 11 * 8); return 0; } @@ -239,15 +240,16 @@ static int mlp_parse(AVCodecParserContext *s, sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba; if (!sync_present) { - // First nibble of a frame is a parity check of the first few nibbles. + /* The first nibble of a frame is a parity check of the 4-byte + * access unit header and all the 2- or 4-byte substream headers. */ // Only check when this isn't a sync frame - syncs have a checksum. parity_bits = 0; - for (i = 0; i <= mp->num_substreams; i++) { + for (i = -1; i < mp->num_substreams; i++) { parity_bits ^= buf[p++]; parity_bits ^= buf[p++]; - if (i == 0 || buf[p-2] & 0x80) { + if (i < 0 || buf[p-2] & 0x80) { parity_bits ^= buf[p++]; parity_bits ^= buf[p++]; } @@ -258,9 +260,11 @@ static int mlp_parse(AVCodecParserContext *s, goto lost_sync; } } else { + GetBitContext gb; MLPHeaderInfo mh; - if (ff_mlp_read_major_sync(avctx, &mh, buf + 4, buf_size - 4) < 0) + init_get_bits(&gb, buf + 4, (buf_size - 4) << 3); + if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0) goto lost_sync; #ifdef CONFIG_AUDIO_NONSHORT @@ -295,7 +299,7 @@ static int mlp_parse(AVCodecParserContext *s, lost_sync: mp->in_sync = 0; - return -1; + return 1; } AVCodecParser mlp_parser = { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mlp_parser.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mlp_parser.h @@ -27,7 +27,7 @@ #ifndef FFMPEG_MLP_PARSER_H #define FFMPEG_MLP_PARSER_H -#include <inttypes.h> +#include "bitstream.h" typedef struct MLPHeaderInfo { @@ -53,8 +53,7 @@ typedef struct MLPHeaderInfo } MLPHeaderInfo; -int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, const uint8_t *buf, - unsigned int buf_size); +int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb); #endif /* FFMPEG_MLP_PARSER_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mlpdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mlpdec.c @@ -0,0 +1,1183 @@ +/* + * MLP decoder + * Copyright (c) 2007-2008 Ian Caulfield + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file mlpdec.c + * MLP decoder + */ + +#include <stdint.h> + +#include "avcodec.h" +#include "libavutil/intreadwrite.h" +#include "bitstream.h" +#include "libavutil/crc.h" +#include "parser.h" +#include "mlp_parser.h" + +/** Maximum number of channels that can be decoded. */ +#define MAX_CHANNELS 16 + +/** Maximum number of matrices used in decoding; most streams have one matrix + * per output channel, but some rematrix a channel (usually 0) more than once. + */ + +#define MAX_MATRICES 15 + +/** Maximum number of substreams that can be decoded. This could also be set + * higher, but I haven't seen any examples with more than two. */ +#define MAX_SUBSTREAMS 2 + +/** maximum sample frequency seen in files */ +#define MAX_SAMPLERATE 192000 + +/** maximum number of audio samples within one access unit */ +#define MAX_BLOCKSIZE (40 * (MAX_SAMPLERATE / 48000)) +/** next power of two greater than MAX_BLOCKSIZE */ +#define MAX_BLOCKSIZE_POW2 (64 * (MAX_SAMPLERATE / 48000)) + +/** number of allowed filters */ +#define NUM_FILTERS 2 + +/** The maximum number of taps in either the IIR or FIR filter; + * I believe MLP actually specifies the maximum order for IIR filters as four, + * and that the sum of the orders of both filters must be <= 8. */ +#define MAX_FILTER_ORDER 8 + +/** number of bits used for VLC lookup - longest Huffman code is 9 */ +#define VLC_BITS 9 + + +static const char* sample_message = + "Please file a bug report following the instructions at " + "http://ffmpeg.mplayerhq.hu/bugreports.html and include " + "a sample of this file."; + +typedef struct SubStream { + //! Set if a valid restart header has been read. Otherwise the substream cannot be decoded. + uint8_t restart_seen; + + //@{ + /** restart header data */ + //! The type of noise to be used in the rematrix stage. + uint16_t noise_type; + + //! The index of the first channel coded in this substream. + uint8_t min_channel; + //! The index of the last channel coded in this substream. + uint8_t max_channel; + //! The number of channels input into the rematrix stage. + uint8_t max_matrix_channel; + + //! The left shift applied to random noise in 0x31ea substreams. + uint8_t noise_shift; + //! The current seed value for the pseudorandom noise generator(s). + uint32_t noisegen_seed; + + //! Set if the substream contains extra info to check the size of VLC blocks. + uint8_t data_check_present; + + //! Bitmask of which parameter sets are conveyed in a decoding parameter block. + uint8_t param_presence_flags; +#define PARAM_BLOCKSIZE (1 << 7) +#define PARAM_MATRIX (1 << 6) +#define PARAM_OUTSHIFT (1 << 5) +#define PARAM_QUANTSTEP (1 << 4) +#define PARAM_FIR (1 << 3) +#define PARAM_IIR (1 << 2) +#define PARAM_HUFFOFFSET (1 << 1) + //@} + + //@{ + /** matrix data */ + + //! Number of matrices to be applied. + uint8_t num_primitive_matrices; + + //! matrix output channel + uint8_t matrix_out_ch[MAX_MATRICES]; + + //! Whether the LSBs of the matrix output are encoded in the bitstream. + uint8_t lsb_bypass[MAX_MATRICES]; + //! Matrix coefficients, stored as 2.14 fixed point. + int32_t matrix_coeff[MAX_MATRICES][MAX_CHANNELS+2]; + //! Left shift to apply to noise values in 0x31eb substreams. + uint8_t matrix_noise_shift[MAX_MATRICES]; + //@} + + //! Left shift to apply to Huffman-decoded residuals. + uint8_t quant_step_size[MAX_CHANNELS]; + + //! number of PCM samples in current audio block + uint16_t blocksize; + //! Number of PCM samples decoded so far in this frame. + uint16_t blockpos; + + //! Left shift to apply to decoded PCM values to get final 24-bit output. + int8_t output_shift[MAX_CHANNELS]; + + //! Running XOR of all output samples. + int32_t lossless_check_data; + +} SubStream; + +typedef struct MLPDecodeContext { + AVCodecContext *avctx; + + //! Set if a valid major sync block has been read. Otherwise no decoding is possible. + uint8_t params_valid; + + //! Number of substreams contained within this stream. + uint8_t num_substreams; + + //! Index of the last substream to decode - further substreams are skipped. + uint8_t max_decoded_substream; + + //! number of PCM samples contained in each frame + int access_unit_size; + //! next power of two above the number of samples in each frame + int access_unit_size_pow2; + + SubStream substream[MAX_SUBSTREAMS]; + + //@{ + /** filter data */ +#define FIR 0 +#define IIR 1 + //! number of taps in filter + uint8_t filter_order[MAX_CHANNELS][NUM_FILTERS]; + //! Right shift to apply to output of filter. + uint8_t filter_shift[MAX_CHANNELS][NUM_FILTERS]; + + int32_t filter_coeff[MAX_CHANNELS][NUM_FILTERS][MAX_FILTER_ORDER]; + int32_t filter_state[MAX_CHANNELS][NUM_FILTERS][MAX_FILTER_ORDER]; + //@} + + //@{ + /** sample data coding information */ + //! Offset to apply to residual values. + int16_t huff_offset[MAX_CHANNELS]; + //! sign/rounding-corrected version of huff_offset + int32_t sign_huff_offset[MAX_CHANNELS]; + //! Which VLC codebook to use to read residuals. + uint8_t codebook[MAX_CHANNELS]; + //! Size of residual suffix not encoded using VLC. + uint8_t huff_lsbs[MAX_CHANNELS]; + //@} + + int8_t noise_buffer[MAX_BLOCKSIZE_POW2]; + int8_t bypassed_lsbs[MAX_BLOCKSIZE][MAX_CHANNELS]; + int32_t sample_buffer[MAX_BLOCKSIZE][MAX_CHANNELS+2]; +} MLPDecodeContext; + +/** Tables defining the Huffman codes. + * There are three entropy coding methods used in MLP (four if you count + * "none" as a method). These use the same sequences for codes starting with + * 00 or 01, but have different codes starting with 1. */ + +static const uint8_t huffman_tables[3][18][2] = { + { /* Huffman table 0, -7 - +10 */ + {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, + {0x04, 3}, {0x05, 3}, {0x06, 3}, {0x07, 3}, + {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, + }, { /* Huffman table 1, -7 - +8 */ + {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, + {0x02, 2}, {0x03, 2}, + {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, + }, { /* Huffman table 2, -7 - +7 */ + {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, + {0x01, 1}, + {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, + } +}; + +static VLC huff_vlc[3]; + +static int crc_init = 0; +static AVCRC crc_63[1024]; +static AVCRC crc_1D[1024]; + + +/** Initialize static data, constant between all invocations of the codec. */ + +static av_cold void init_static() +{ + INIT_VLC_STATIC(&huff_vlc[0], VLC_BITS, 18, + &huffman_tables[0][0][1], 2, 1, + &huffman_tables[0][0][0], 2, 1, 512); + INIT_VLC_STATIC(&huff_vlc[1], VLC_BITS, 16, + &huffman_tables[1][0][1], 2, 1, + &huffman_tables[1][0][0], 2, 1, 512); + INIT_VLC_STATIC(&huff_vlc[2], VLC_BITS, 15, + &huffman_tables[2][0][1], 2, 1, + &huffman_tables[2][0][0], 2, 1, 512); + + if (!crc_init) { + av_crc_init(crc_63, 0, 8, 0x63, sizeof(crc_63)); + av_crc_init(crc_1D, 0, 8, 0x1D, sizeof(crc_1D)); + crc_init = 1; + } +} + + +/** MLP uses checksums that seem to be based on the standard CRC algorithm, but + * are not (in implementation terms, the table lookup and XOR are reversed). + * We can implement this behavior using a standard av_crc on all but the + * last element, then XOR that with the last element. */ + +static uint8_t mlp_checksum8(const uint8_t *buf, unsigned int buf_size) +{ + uint8_t checksum = av_crc(crc_63, 0x3c, buf, buf_size - 1); // crc_63[0xa2] == 0x3c + checksum ^= buf[buf_size-1]; + return checksum; +} + +/** Calculate an 8-bit checksum over a restart header -- a non-multiple-of-8 + * number of bits, starting two bits into the first byte of buf. */ + +static uint8_t mlp_restart_checksum(const uint8_t *buf, unsigned int bit_size) +{ + int i; + int num_bytes = (bit_size + 2) / 8; + + int crc = crc_1D[buf[0] & 0x3f]; + crc = av_crc(crc_1D, crc, buf + 1, num_bytes - 2); + crc ^= buf[num_bytes - 1]; + + for (i = 0; i < ((bit_size + 2) & 7); i++) { + crc <<= 1; + if (crc & 0x100) + crc ^= 0x11D; + crc ^= (buf[num_bytes] >> (7 - i)) & 1; + } + + return crc; +} + +static inline int32_t calculate_sign_huff(MLPDecodeContext *m, + unsigned int substr, unsigned int ch) +{ + SubStream *s = &m->substream[substr]; + int lsb_bits = m->huff_lsbs[ch] - s->quant_step_size[ch]; + int sign_shift = lsb_bits + (m->codebook[ch] ? 2 - m->codebook[ch] : -1); + int32_t sign_huff_offset = m->huff_offset[ch]; + + if (m->codebook[ch] > 0) + sign_huff_offset -= 7 << lsb_bits; + + if (sign_shift >= 0) + sign_huff_offset -= 1 << sign_shift; + + return sign_huff_offset; +} + +/** Read a sample, consisting of either, both or neither of entropy-coded MSBs + * and plain LSBs. */ + +static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp, + unsigned int substr, unsigned int pos) +{ + SubStream *s = &m->substream[substr]; + unsigned int mat, channel; + + for (mat = 0; mat < s->num_primitive_matrices; mat++) + if (s->lsb_bypass[mat]) + m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp); + + for (channel = s->min_channel; channel <= s->max_channel; channel++) { + int codebook = m->codebook[channel]; + int quant_step_size = s->quant_step_size[channel]; + int lsb_bits = m->huff_lsbs[channel] - quant_step_size; + int result = 0; + + if (codebook > 0) + result = get_vlc2(gbp, huff_vlc[codebook-1].table, + VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS); + + if (result < 0) + return -1; + + if (lsb_bits > 0) + result = (result << lsb_bits) + get_bits(gbp, lsb_bits); + + result += m->sign_huff_offset[channel]; + result <<= quant_step_size; + + m->sample_buffer[pos + s->blockpos][channel] = result; + } + + return 0; +} + +static av_cold int mlp_decode_init(AVCodecContext *avctx) +{ + MLPDecodeContext *m = avctx->priv_data; + int substr; + + init_static(); + m->avctx = avctx; + for (substr = 0; substr < MAX_SUBSTREAMS; substr++) + m->substream[substr].lossless_check_data = 0xffffffff; + return 0; +} + +/** Read a major sync info header - contains high level information about + * the stream - sample rate, channel arrangement etc. Most of this + * information is not actually necessary for decoding, only for playback. + */ + +static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) +{ + MLPHeaderInfo mh; + int substr; + + if (ff_mlp_read_major_sync(m->avctx, &mh, gb) != 0) + return -1; + + if (mh.group1_bits == 0) { + av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown bits per sample\n"); + return -1; + } + if (mh.group2_bits > mh.group1_bits) { + av_log(m->avctx, AV_LOG_ERROR, + "Channel group 2 cannot have more bits per sample than group 1.\n"); + return -1; + } + + if (mh.group2_samplerate && mh.group2_samplerate != mh.group1_samplerate) { + av_log(m->avctx, AV_LOG_ERROR, + "Channel groups with differing sample rates are not currently supported.\n"); + return -1; + } + + if (mh.group1_samplerate == 0) { + av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown sampling rate\n"); + return -1; + } + if (mh.group1_samplerate > MAX_SAMPLERATE) { + av_log(m->avctx, AV_LOG_ERROR, + "Sampling rate %d is greater than the supported maximum (%d).\n", + mh.group1_samplerate, MAX_SAMPLERATE); + return -1; + } + if (mh.access_unit_size > MAX_BLOCKSIZE) { + av_log(m->avctx, AV_LOG_ERROR, + "Block size %d is greater than the supported maximum (%d).\n", + mh.access_unit_size, MAX_BLOCKSIZE); + return -1; + } + if (mh.access_unit_size_pow2 > MAX_BLOCKSIZE_POW2) { + av_log(m->avctx, AV_LOG_ERROR, + "Block size pow2 %d is greater than the supported maximum (%d).\n", + mh.access_unit_size_pow2, MAX_BLOCKSIZE_POW2); + return -1; + } + + if (mh.num_substreams == 0) + return -1; + if (mh.num_substreams > MAX_SUBSTREAMS) { + av_log(m->avctx, AV_LOG_ERROR, + "Number of substreams %d is larger than the maximum supported " + "by the decoder. %s\n", mh.num_substreams, sample_message); + return -1; + } + + m->access_unit_size = mh.access_unit_size; + m->access_unit_size_pow2 = mh.access_unit_size_pow2; + + m->num_substreams = mh.num_substreams; + m->max_decoded_substream = m->num_substreams - 1; + + m->avctx->sample_rate = mh.group1_samplerate; + m->avctx->frame_size = mh.access_unit_size; + +#ifdef CONFIG_AUDIO_NONSHORT + m->avctx->bits_per_sample = mh.group1_bits; + if (mh.group1_bits > 16) { + m->avctx->sample_fmt = SAMPLE_FMT_S32; + } +#endif + + m->params_valid = 1; + for (substr = 0; substr < MAX_SUBSTREAMS; substr++) + m->substream[substr].restart_seen = 0; + + return 0; +} + +/** Read a restart header from a block in a substream. This contains parameters + * required to decode the audio that do not change very often. Generally + * (always) present only in blocks following a major sync. */ + +static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, + const uint8_t *buf, unsigned int substr) +{ + SubStream *s = &m->substream[substr]; + unsigned int ch; + int sync_word, tmp; + uint8_t checksum; + uint8_t lossless_check; + int start_count = get_bits_count(gbp); + + sync_word = get_bits(gbp, 13); + + if (sync_word != 0x31ea >> 1) { + av_log(m->avctx, AV_LOG_ERROR, + "restart header sync incorrect (got 0x%04x)\n", sync_word); + return -1; + } + s->noise_type = get_bits1(gbp); + + skip_bits(gbp, 16); /* Output timestamp */ + + s->min_channel = get_bits(gbp, 4); + s->max_channel = get_bits(gbp, 4); + s->max_matrix_channel = get_bits(gbp, 4); + + if (s->min_channel > s->max_channel) { + av_log(m->avctx, AV_LOG_ERROR, + "Substream min channel cannot be greater than max channel.\n"); + return -1; + } + + if (m->avctx->request_channels > 0 + && s->max_channel + 1 >= m->avctx->request_channels + && substr < m->max_decoded_substream) { + av_log(m->avctx, AV_LOG_INFO, + "Extracting %d channel downmix from substream %d. " + "Further substreams will be skipped.\n", + s->max_channel + 1, substr); + m->max_decoded_substream = substr; + } + + s->noise_shift = get_bits(gbp, 4); + s->noisegen_seed = get_bits(gbp, 23); + + skip_bits(gbp, 19); + + s->data_check_present = get_bits1(gbp); + lossless_check = get_bits(gbp, 8); + if (substr == m->max_decoded_substream + && s->lossless_check_data != 0xffffffff) { + tmp = s->lossless_check_data; + tmp ^= tmp >> 16; + tmp ^= tmp >> 8; + tmp &= 0xff; + if (tmp != lossless_check) + av_log(m->avctx, AV_LOG_WARNING, + "Lossless check failed - expected %02x, calculated %02x.\n", + lossless_check, tmp); + else + dprintf(m->avctx, "Lossless check passed for substream %d (%x).\n", + substr, tmp); + } + + skip_bits(gbp, 16); + + for (ch = 0; ch <= s->max_matrix_channel; ch++) { + int ch_assign = get_bits(gbp, 6); + dprintf(m->avctx, "ch_assign[%d][%d] = %d\n", substr, ch, + ch_assign); + if (ch_assign != ch) { + av_log(m->avctx, AV_LOG_ERROR, + "Non-1:1 channel assignments are used in this stream. %s\n", + sample_message); + return -1; + } + } + + checksum = mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); + + if (checksum != get_bits(gbp, 8)) + av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n"); + + /* Set default decoding parameters. */ + s->param_presence_flags = 0xff; + s->num_primitive_matrices = 0; + s->blocksize = 8; + s->lossless_check_data = 0; + + memset(s->output_shift , 0, sizeof(s->output_shift )); + memset(s->quant_step_size, 0, sizeof(s->quant_step_size)); + + for (ch = s->min_channel; ch <= s->max_channel; ch++) { + m->filter_order[ch][FIR] = 0; + m->filter_order[ch][IIR] = 0; + m->filter_shift[ch][FIR] = 0; + m->filter_shift[ch][IIR] = 0; + + /* Default audio coding is 24-bit raw PCM. */ + m->huff_offset [ch] = 0; + m->sign_huff_offset[ch] = (-1) << 23; + m->codebook [ch] = 0; + m->huff_lsbs [ch] = 24; + } + + if (substr == m->max_decoded_substream) { + m->avctx->channels = s->max_channel + 1; + } + + return 0; +} + +/** Read parameters for one of the prediction filters. */ + +static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, + unsigned int channel, unsigned int filter) +{ + const char fchar = filter ? 'I' : 'F'; + int i, order; + + // Filter is 0 for FIR, 1 for IIR. + assert(filter < 2); + + order = get_bits(gbp, 4); + if (order > MAX_FILTER_ORDER) { + av_log(m->avctx, AV_LOG_ERROR, + "%cIR filter order %d is greater than maximum %d.\n", + fchar, order, MAX_FILTER_ORDER); + return -1; + } + m->filter_order[channel][filter] = order; + + if (order > 0) { + int coeff_bits, coeff_shift; + + m->filter_shift[channel][filter] = get_bits(gbp, 4); + + coeff_bits = get_bits(gbp, 5); + coeff_shift = get_bits(gbp, 3); + if (coeff_bits < 1 || coeff_bits > 16) { + av_log(m->avctx, AV_LOG_ERROR, + "%cIR filter coeff_bits must be between 1 and 16.\n", + fchar); + return -1; + } + if (coeff_bits + coeff_shift > 16) { + av_log(m->avctx, AV_LOG_ERROR, + "Sum of coeff_bits and coeff_shift for %cIR filter must be 16 or less.\n", + fchar); + return -1; + } + + for (i = 0; i < order; i++) + m->filter_coeff[channel][filter][i] = + get_sbits(gbp, coeff_bits) << coeff_shift; + + if (get_bits1(gbp)) { + int state_bits, state_shift; + + if (filter == FIR) { + av_log(m->avctx, AV_LOG_ERROR, + "FIR filter has state data specified.\n"); + return -1; + } + + state_bits = get_bits(gbp, 4); + state_shift = get_bits(gbp, 4); + + /* TODO: Check validity of state data. */ + + for (i = 0; i < order; i++) + m->filter_state[channel][filter][i] = + get_sbits(gbp, state_bits) << state_shift; + } + } + + return 0; +} + +/** Read decoding parameters that change more often than those in the restart + * header. */ + +static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, + unsigned int substr) +{ + SubStream *s = &m->substream[substr]; + unsigned int mat, ch; + + if (get_bits1(gbp)) + s->param_presence_flags = get_bits(gbp, 8); + + if (s->param_presence_flags & PARAM_BLOCKSIZE) + if (get_bits1(gbp)) { + s->blocksize = get_bits(gbp, 9); + if (s->blocksize > MAX_BLOCKSIZE) { + av_log(m->avctx, AV_LOG_ERROR, "block size too large\n"); + s->blocksize = 0; + return -1; + } + } + + if (s->param_presence_flags & PARAM_MATRIX) + if (get_bits1(gbp)) { + s->num_primitive_matrices = get_bits(gbp, 4); + + for (mat = 0; mat < s->num_primitive_matrices; mat++) { + int frac_bits, max_chan; + s->matrix_out_ch[mat] = get_bits(gbp, 4); + frac_bits = get_bits(gbp, 4); + s->lsb_bypass [mat] = get_bits1(gbp); + + if (s->matrix_out_ch[mat] > s->max_channel) { + av_log(m->avctx, AV_LOG_ERROR, + "Invalid channel %d specified as output from matrix.\n", + s->matrix_out_ch[mat]); + return -1; + } + if (frac_bits > 14) { + av_log(m->avctx, AV_LOG_ERROR, + "Too many fractional bits specified.\n"); + return -1; + } + + max_chan = s->max_matrix_channel; + if (!s->noise_type) + max_chan+=2; + + for (ch = 0; ch <= max_chan; ch++) { + int coeff_val = 0; + if (get_bits1(gbp)) + coeff_val = get_sbits(gbp, frac_bits + 2); + + s->matrix_coeff[mat][ch] = coeff_val << (14 - frac_bits); + } + + if (s->noise_type) + s->matrix_noise_shift[mat] = get_bits(gbp, 4); + else + s->matrix_noise_shift[mat] = 0; + } + } + + if (s->param_presence_flags & PARAM_OUTSHIFT) + if (get_bits1(gbp)) + for (ch = 0; ch <= s->max_matrix_channel; ch++) { + s->output_shift[ch] = get_bits(gbp, 4); + dprintf(m->avctx, "output shift[%d] = %d\n", + ch, s->output_shift[ch]); + /* TODO: validate */ + } + + if (s->param_presence_flags & PARAM_QUANTSTEP) + if (get_bits1(gbp)) + for (ch = 0; ch <= s->max_channel; ch++) { + s->quant_step_size[ch] = get_bits(gbp, 4); + /* TODO: validate */ + + m->sign_huff_offset[ch] = calculate_sign_huff(m, substr, ch); + } + + for (ch = s->min_channel; ch <= s->max_channel; ch++) + if (get_bits1(gbp)) { + if (s->param_presence_flags & PARAM_FIR) + if (get_bits1(gbp)) + if (read_filter_params(m, gbp, ch, FIR) < 0) + return -1; + + if (s->param_presence_flags & PARAM_IIR) + if (get_bits1(gbp)) + if (read_filter_params(m, gbp, ch, IIR) < 0) + return -1; + + if (m->filter_order[ch][FIR] && m->filter_order[ch][IIR] && + m->filter_shift[ch][FIR] != m->filter_shift[ch][IIR]) { + av_log(m->avctx, AV_LOG_ERROR, + "FIR and IIR filters must use the same precision.\n"); + return -1; + } + /* The FIR and IIR filters must have the same precision. + * To simplify the filtering code, only the precision of the + * FIR filter is considered. If only the IIR filter is employed, + * the FIR filter precision is set to that of the IIR filter, so + * that the filtering code can use it. */ + if (!m->filter_order[ch][FIR] && m->filter_order[ch][IIR]) + m->filter_shift[ch][FIR] = m->filter_shift[ch][IIR]; + + if (s->param_presence_flags & PARAM_HUFFOFFSET) + if (get_bits1(gbp)) + m->huff_offset[ch] = get_sbits(gbp, 15); + + m->codebook [ch] = get_bits(gbp, 2); + m->huff_lsbs[ch] = get_bits(gbp, 5); + + m->sign_huff_offset[ch] = calculate_sign_huff(m, substr, ch); + + /* TODO: validate */ + } + + return 0; +} + +#define MSB_MASK(bits) (-1u << bits) + +/** Generate PCM samples using the prediction filters and residual values + * read from the data stream, and update the filter state. */ + +static void filter_channel(MLPDecodeContext *m, unsigned int substr, + unsigned int channel) +{ + SubStream *s = &m->substream[substr]; + int32_t filter_state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FILTER_ORDER]; + unsigned int filter_shift = m->filter_shift[channel][FIR]; + int32_t mask = MSB_MASK(s->quant_step_size[channel]); + int index = MAX_BLOCKSIZE; + int j, i; + + for (j = 0; j < NUM_FILTERS; j++) { + memcpy(& filter_state_buffer [j][MAX_BLOCKSIZE], + &m->filter_state[channel][j][0], + MAX_FILTER_ORDER * sizeof(int32_t)); + } + + for (i = 0; i < s->blocksize; i++) { + int32_t residual = m->sample_buffer[i + s->blockpos][channel]; + unsigned int order; + int64_t accum = 0; + int32_t result; + + /* TODO: Move this code to DSPContext? */ + + for (j = 0; j < NUM_FILTERS; j++) + for (order = 0; order < m->filter_order[channel][j]; order++) + accum += (int64_t)filter_state_buffer[j][index + order] * + m->filter_coeff[channel][j][order]; + + accum = accum >> filter_shift; + result = (accum + residual) & mask; + + --index; + + filter_state_buffer[FIR][index] = result; + filter_state_buffer[IIR][index] = result - accum; + + m->sample_buffer[i + s->blockpos][channel] = result; + } + + for (j = 0; j < NUM_FILTERS; j++) { + memcpy(&m->filter_state[channel][j][0], + & filter_state_buffer [j][index], + MAX_FILTER_ORDER * sizeof(int32_t)); + } +} + +/** Read a block of PCM residual data (or actual if no filtering active). */ + +static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, + unsigned int substr) +{ + SubStream *s = &m->substream[substr]; + unsigned int i, ch, expected_stream_pos = 0; + + if (s->data_check_present) { + expected_stream_pos = get_bits_count(gbp); + expected_stream_pos += get_bits(gbp, 16); + av_log(m->avctx, AV_LOG_WARNING, "This file contains some features " + "we have not tested yet. %s\n", sample_message); + } + + if (s->blockpos + s->blocksize > m->access_unit_size) { + av_log(m->avctx, AV_LOG_ERROR, "too many audio samples in frame\n"); + return -1; + } + + memset(&m->bypassed_lsbs[s->blockpos][0], 0, + s->blocksize * sizeof(m->bypassed_lsbs[0])); + + for (i = 0; i < s->blocksize; i++) { + if (read_huff_channels(m, gbp, substr, i) < 0) + return -1; + } + + for (ch = s->min_channel; ch <= s->max_channel; ch++) { + filter_channel(m, substr, ch); + } + + s->blockpos += s->blocksize; + + if (s->data_check_present) { + if (get_bits_count(gbp) != expected_stream_pos) + av_log(m->avctx, AV_LOG_ERROR, "block data length mismatch\n"); + skip_bits(gbp, 8); + } + + return 0; +} + +/** Data table used for TrueHD noise generation function. */ + +static const int8_t noise_table[256] = { + 30, 51, 22, 54, 3, 7, -4, 38, 14, 55, 46, 81, 22, 58, -3, 2, + 52, 31, -7, 51, 15, 44, 74, 30, 85, -17, 10, 33, 18, 80, 28, 62, + 10, 32, 23, 69, 72, 26, 35, 17, 73, 60, 8, 56, 2, 6, -2, -5, + 51, 4, 11, 50, 66, 76, 21, 44, 33, 47, 1, 26, 64, 48, 57, 40, + 38, 16, -10, -28, 92, 22, -18, 29, -10, 5, -13, 49, 19, 24, 70, 34, + 61, 48, 30, 14, -6, 25, 58, 33, 42, 60, 67, 17, 54, 17, 22, 30, + 67, 44, -9, 50, -11, 43, 40, 32, 59, 82, 13, 49, -14, 55, 60, 36, + 48, 49, 31, 47, 15, 12, 4, 65, 1, 23, 29, 39, 45, -2, 84, 69, + 0, 72, 37, 57, 27, 41, -15, -16, 35, 31, 14, 61, 24, 0, 27, 24, + 16, 41, 55, 34, 53, 9, 56, 12, 25, 29, 53, 5, 20, -20, -8, 20, + 13, 28, -3, 78, 38, 16, 11, 62, 46, 29, 21, 24, 46, 65, 43, -23, + 89, 18, 74, 21, 38, -12, 19, 12, -19, 8, 15, 33, 4, 57, 9, -8, + 36, 35, 26, 28, 7, 83, 63, 79, 75, 11, 3, 87, 37, 47, 34, 40, + 39, 19, 20, 42, 27, 34, 39, 77, 13, 42, 59, 64, 45, -1, 32, 37, + 45, -5, 53, -6, 7, 36, 50, 23, 6, 32, 9, -21, 18, 71, 27, 52, + -25, 31, 35, 42, -1, 68, 63, 52, 26, 43, 66, 37, 41, 25, 40, 70, +}; + +/** Noise generation functions. + * I'm not sure what these are for - they seem to be some kind of pseudorandom + * sequence generators, used to generate noise data which is used when the + * channels are rematrixed. I'm not sure if they provide a practical benefit + * to compression, or just obfuscate the decoder. Are they for some kind of + * dithering? */ + +/** Generate two channels of noise, used in the matrix when + * restart sync word == 0x31ea. */ + +static void generate_2_noise_channels(MLPDecodeContext *m, unsigned int substr) +{ + SubStream *s = &m->substream[substr]; + unsigned int i; + uint32_t seed = s->noisegen_seed; + unsigned int maxchan = s->max_matrix_channel; + + for (i = 0; i < s->blockpos; i++) { + uint16_t seed_shr7 = seed >> 7; + m->sample_buffer[i][maxchan+1] = ((int8_t)(seed >> 15)) << s->noise_shift; + m->sample_buffer[i][maxchan+2] = ((int8_t) seed_shr7) << s->noise_shift; + + seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5); + } + + s->noisegen_seed = seed; +} + +/** Generate a block of noise, used when restart sync word == 0x31eb. */ + +static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr) +{ + SubStream *s = &m->substream[substr]; + unsigned int i; + uint32_t seed = s->noisegen_seed; + + for (i = 0; i < m->access_unit_size_pow2; i++) { + uint8_t seed_shr15 = seed >> 15; + m->noise_buffer[i] = noise_table[seed_shr15]; + seed = (seed << 8) ^ seed_shr15 ^ (seed_shr15 << 5); + } + + s->noisegen_seed = seed; +} + + +/** Apply the channel matrices in turn to reconstruct the original audio + * samples. */ + +static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) +{ + SubStream *s = &m->substream[substr]; + unsigned int mat, src_ch, i; + unsigned int maxchan; + + maxchan = s->max_matrix_channel; + if (!s->noise_type) { + generate_2_noise_channels(m, substr); + maxchan += 2; + } else { + fill_noise_buffer(m, substr); + } + + for (mat = 0; mat < s->num_primitive_matrices; mat++) { + int matrix_noise_shift = s->matrix_noise_shift[mat]; + unsigned int dest_ch = s->matrix_out_ch[mat]; + int32_t mask = MSB_MASK(s->quant_step_size[dest_ch]); + + /* TODO: DSPContext? */ + + for (i = 0; i < s->blockpos; i++) { + int64_t accum = 0; + for (src_ch = 0; src_ch <= maxchan; src_ch++) { + accum += (int64_t)m->sample_buffer[i][src_ch] + * s->matrix_coeff[mat][src_ch]; + } + if (matrix_noise_shift) { + uint32_t index = s->num_primitive_matrices - mat; + index = (i * (index * 2 + 1) + index) & (m->access_unit_size_pow2 - 1); + accum += m->noise_buffer[index] << (matrix_noise_shift + 7); + } + m->sample_buffer[i][dest_ch] = ((accum >> 14) & mask) + + m->bypassed_lsbs[i][mat]; + } + } +} + +/** Write the audio data into the output buffer. */ + +static int output_data_internal(MLPDecodeContext *m, unsigned int substr, + uint8_t *data, unsigned int *data_size, int is32) +{ + SubStream *s = &m->substream[substr]; + unsigned int i, ch = 0; + int32_t *data_32 = (int32_t*) data; + int16_t *data_16 = (int16_t*) data; + + if (*data_size < (s->max_channel + 1) * s->blockpos * (is32 ? 4 : 2)) + return -1; + + for (i = 0; i < s->blockpos; i++) { + for (ch = 0; ch <= s->max_channel; ch++) { + int32_t sample = m->sample_buffer[i][ch] << s->output_shift[ch]; + s->lossless_check_data ^= (sample & 0xffffff) << ch; + if (is32) *data_32++ = sample << 8; + else *data_16++ = sample >> 8; + } + } + + *data_size = i * ch * (is32 ? 4 : 2); + + return 0; +} + +static int output_data(MLPDecodeContext *m, unsigned int substr, + uint8_t *data, unsigned int *data_size) +{ + if (m->avctx->sample_fmt == SAMPLE_FMT_S32) + return output_data_internal(m, substr, data, data_size, 1); + else + return output_data_internal(m, substr, data, data_size, 0); +} + + +/** XOR together all the bytes of a buffer. + * Does this belong in dspcontext? */ + +static uint8_t calculate_parity(const uint8_t *buf, unsigned int buf_size) +{ + uint32_t scratch = 0; + const uint8_t *buf_end = buf + buf_size; + + for (; buf < buf_end - 3; buf += 4) + scratch ^= *((const uint32_t*)buf); + + scratch ^= scratch >> 16; + scratch ^= scratch >> 8; + + for (; buf < buf_end; buf++) + scratch ^= *buf; + + return scratch; +} + +/** Read an access unit from the stream. + * Returns < 0 on error, 0 if not enough data is present in the input stream + * otherwise returns the number of bytes consumed. */ + +static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size, + const uint8_t *buf, int buf_size) +{ + MLPDecodeContext *m = avctx->priv_data; + GetBitContext gb; + unsigned int length, substr; + unsigned int substream_start; + unsigned int header_size = 4; + unsigned int substr_header_size = 0; + uint8_t substream_parity_present[MAX_SUBSTREAMS]; + uint16_t substream_data_len[MAX_SUBSTREAMS]; + uint8_t parity_bits; + + if (buf_size < 4) + return 0; + + length = (AV_RB16(buf) & 0xfff) * 2; + + if (length > buf_size) + return -1; + + init_get_bits(&gb, (buf + 4), (length - 4) * 8); + + if (show_bits_long(&gb, 31) == (0xf8726fba >> 1)) { + dprintf(m->avctx, "Found major sync.\n"); + if (read_major_sync(m, &gb) < 0) + goto error; + header_size += 28; + } + + if (!m->params_valid) { + av_log(m->avctx, AV_LOG_WARNING, + "Stream parameters not seen; skipping frame.\n"); + *data_size = 0; + return length; + } + + substream_start = 0; + + for (substr = 0; substr < m->num_substreams; substr++) { + int extraword_present, checkdata_present, end; + + extraword_present = get_bits1(&gb); + skip_bits1(&gb); + checkdata_present = get_bits1(&gb); + skip_bits1(&gb); + + end = get_bits(&gb, 12) * 2; + + substr_header_size += 2; + + if (extraword_present) { + skip_bits(&gb, 16); + substr_header_size += 2; + } + + if (end + header_size + substr_header_size > length) { + av_log(m->avctx, AV_LOG_ERROR, + "Indicated length of substream %d data goes off end of " + "packet.\n", substr); + end = length - header_size - substr_header_size; + } + + if (end < substream_start) { + av_log(avctx, AV_LOG_ERROR, + "Indicated end offset of substream %d data " + "is smaller than calculated start offset.\n", + substr); + goto error; + } + + if (substr > m->max_decoded_substream) + continue; + + substream_parity_present[substr] = checkdata_present; + substream_data_len[substr] = end - substream_start; + substream_start = end; + } + + parity_bits = calculate_parity(buf, 4); + parity_bits ^= calculate_parity(buf + header_size, substr_header_size); + + if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) { + av_log(avctx, AV_LOG_ERROR, "Parity check failed.\n"); + goto error; + } + + buf += header_size + substr_header_size; + + for (substr = 0; substr <= m->max_decoded_substream; substr++) { + SubStream *s = &m->substream[substr]; + init_get_bits(&gb, buf, substream_data_len[substr] * 8); + + s->blockpos = 0; + do { + if (get_bits1(&gb)) { + if (get_bits1(&gb)) { + /* A restart header should be present. */ + if (read_restart_header(m, &gb, buf, substr) < 0) + goto next_substr; + s->restart_seen = 1; + } + + if (!s->restart_seen) { + av_log(m->avctx, AV_LOG_ERROR, + "No restart header present in substream %d.\n", + substr); + goto next_substr; + } + + if (read_decoding_params(m, &gb, substr) < 0) + goto next_substr; + } + + if (!s->restart_seen) { + av_log(m->avctx, AV_LOG_ERROR, + "No restart header present in substream %d.\n", + substr); + goto next_substr; + } + + if (read_block_data(m, &gb, substr) < 0) + return -1; + + } while ((get_bits_count(&gb) < substream_data_len[substr] * 8) + && get_bits1(&gb) == 0); + + skip_bits(&gb, (-get_bits_count(&gb)) & 15); + if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32 && + (show_bits_long(&gb, 32) == 0xd234d234 || + show_bits_long(&gb, 20) == 0xd234e)) { + skip_bits(&gb, 18); + if (substr == m->max_decoded_substream) + av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n"); + + if (get_bits1(&gb)) { + int shorten_by = get_bits(&gb, 13); + shorten_by = FFMIN(shorten_by, s->blockpos); + s->blockpos -= shorten_by; + } else + skip_bits(&gb, 13); + } + if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 16 && + substream_parity_present[substr]) { + uint8_t parity, checksum; + + parity = calculate_parity(buf, substream_data_len[substr] - 2); + if ((parity ^ get_bits(&gb, 8)) != 0xa9) + av_log(m->avctx, AV_LOG_ERROR, + "Substream %d parity check failed.\n", substr); + + checksum = mlp_checksum8(buf, substream_data_len[substr] - 2); + if (checksum != get_bits(&gb, 8)) + av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n", + substr); + } + if (substream_data_len[substr] * 8 != get_bits_count(&gb)) { + av_log(m->avctx, AV_LOG_ERROR, "substream %d length mismatch\n", + substr); + return -1; + } + +next_substr: + buf += substream_data_len[substr]; + } + + rematrix_channels(m, m->max_decoded_substream); + + if (output_data(m, m->max_decoded_substream, data, data_size) < 0) + return -1; + + return length; + +error: + m->params_valid = 0; + return -1; +} + +AVCodec mlp_decoder = { + "mlp", + CODEC_TYPE_AUDIO, + CODEC_ID_MLP, + sizeof(MLPDecodeContext), + mlp_decode_init, + NULL, + NULL, + read_access_unit, + .long_name = NULL_IF_CONFIG_SMALL("Meridian Lossless Packing"), +}; + diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mmvideo.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mmvideo.c @@ -1,6 +1,6 @@ /* * American Laser Games MM Video Decoder - * Copyright (c) 2006 Peter Ross + * Copyright (c) 2006,2008 Peter Ross * * This file is part of FFmpeg. * @@ -41,10 +41,12 @@ #define MM_TYPE_INTER_HH 0xd #define MM_TYPE_INTRA_HHV 0xe #define MM_TYPE_INTER_HHV 0xf +#define MM_TYPE_PALETTE 0x31 typedef struct MmContext { AVCodecContext *avctx; AVFrame frame; + int palette[AVPALETTE_COUNT]; } MmContext; static av_cold int mm_decode_init(AVCodecContext *avctx) @@ -53,11 +55,6 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) s->avctx = avctx; - if (s->avctx->palctrl == NULL) { - av_log(avctx, AV_LOG_ERROR, "mmvideo: palette expected.\n"); - return -1; - } - avctx->pix_fmt = PIX_FMT_PAL8; if (avcodec_check_dimensions(avctx, avctx->width, avctx->height)) @@ -72,6 +69,17 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) return 0; } +static void mm_decode_pal(MmContext *s, const uint8_t *buf, const uint8_t *buf_end) +{ + int i; + buf += 4; + for (i=0; i<128 && buf+2<buf_end; i++) { + s->palette[i] = AV_RB24(buf); + s->palette[i+128] = s->palette[i]<<2; + buf += 3; + } +} + static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) { int i, x, y; @@ -153,19 +161,15 @@ static int mm_decode_frame(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { MmContext *s = avctx->priv_data; - AVPaletteControl *palette_control = avctx->palctrl; + const uint8_t *buf_end = buf+buf_size; int type; - if (palette_control->palette_changed) { - memcpy(s->frame.data[1], palette_control->palette, AVPALETTE_SIZE); - palette_control->palette_changed = 0; - } - type = AV_RL16(&buf[0]); buf += MM_PREAMBLE_SIZE; buf_size -= MM_PREAMBLE_SIZE; switch(type) { + case MM_TYPE_PALETTE : mm_decode_pal(s, buf, buf_end); return buf_size; case MM_TYPE_INTRA : mm_decode_intra(s, 0, 0, buf, buf_size); break; case MM_TYPE_INTRA_HH : mm_decode_intra(s, 1, 0, buf, buf_size); break; case MM_TYPE_INTRA_HHV : mm_decode_intra(s, 1, 1, buf, buf_size); break; @@ -176,6 +180,8 @@ static int mm_decode_frame(AVCodecContext *avctx, return -1; } + memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/motion_est.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/motion_est.c @@ -338,229 +338,6 @@ static inline void no_motion_search(MpegEncContext * s, *my_ptr = 16 * s->mb_y; } -#if 0 /* the use of these functions is inside #if 0 */ -static int full_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int range, - int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) -{ - int x1, y1, x2, y2, xx, yy, x, y; - int mx, my, dmin, d; - uint8_t *pix; - - xx = 16 * s->mb_x; - yy = 16 * s->mb_y; - x1 = xx - range + 1; /* we loose one pixel to avoid boundary pb with half pixel pred */ - if (x1 < xmin) - x1 = xmin; - x2 = xx + range - 1; - if (x2 > xmax) - x2 = xmax; - y1 = yy - range + 1; - if (y1 < ymin) - y1 = ymin; - y2 = yy + range - 1; - if (y2 > ymax) - y2 = ymax; - pix = s->new_picture.data[0] + (yy * s->linesize) + xx; - dmin = 0x7fffffff; - mx = 0; - my = 0; - for (y = y1; y <= y2; y++) { - for (x = x1; x <= x2; x++) { - d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, - s->linesize, 16); - if (d < dmin || - (d == dmin && - (abs(x - xx) + abs(y - yy)) < - (abs(mx - xx) + abs(my - yy)))) { - dmin = d; - mx = x; - my = y; - } - } - } - - *mx_ptr = mx; - *my_ptr = my; - -#if 0 - if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) || - *my_ptr < -(2 * range) || *my_ptr >= (2 * range)) { - av_log(NULL, AV_LOG_ERROR, "error %d %d\n", *mx_ptr, *my_ptr); - } -#endif - return dmin; -} - - -static int log_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int range, - int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) -{ - int x1, y1, x2, y2, xx, yy, x, y; - int mx, my, dmin, d; - uint8_t *pix; - - xx = s->mb_x << 4; - yy = s->mb_y << 4; - - /* Left limit */ - x1 = xx - range; - if (x1 < xmin) - x1 = xmin; - - /* Right limit */ - x2 = xx + range; - if (x2 > xmax) - x2 = xmax; - - /* Upper limit */ - y1 = yy - range; - if (y1 < ymin) - y1 = ymin; - - /* Lower limit */ - y2 = yy + range; - if (y2 > ymax) - y2 = ymax; - - pix = s->new_picture.data[0] + (yy * s->linesize) + xx; - dmin = 0x7fffffff; - mx = 0; - my = 0; - - do { - for (y = y1; y <= y2; y += range) { - for (x = x1; x <= x2; x += range) { - d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); - if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { - dmin = d; - mx = x; - my = y; - } - } - } - - range = range >> 1; - - x1 = mx - range; - if (x1 < xmin) - x1 = xmin; - - x2 = mx + range; - if (x2 > xmax) - x2 = xmax; - - y1 = my - range; - if (y1 < ymin) - y1 = ymin; - - y2 = my + range; - if (y2 > ymax) - y2 = ymax; - - } while (range >= 1); - -#ifdef DEBUG - av_log(s->avctx, AV_LOG_DEBUG, "log - MX: %d\tMY: %d\n", mx, my); -#endif - *mx_ptr = mx; - *my_ptr = my; - return dmin; -} - -static int phods_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int range, - int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture) -{ - int x1, y1, x2, y2, xx, yy, x, y, lastx, d; - int mx, my, dminx, dminy; - uint8_t *pix; - - xx = s->mb_x << 4; - yy = s->mb_y << 4; - - /* Left limit */ - x1 = xx - range; - if (x1 < xmin) - x1 = xmin; - - /* Right limit */ - x2 = xx + range; - if (x2 > xmax) - x2 = xmax; - - /* Upper limit */ - y1 = yy - range; - if (y1 < ymin) - y1 = ymin; - - /* Lower limit */ - y2 = yy + range; - if (y2 > ymax) - y2 = ymax; - - pix = s->new_picture.data[0] + (yy * s->linesize) + xx; - mx = 0; - my = 0; - - x = xx; - y = yy; - do { - dminx = 0x7fffffff; - dminy = 0x7fffffff; - - lastx = x; - for (x = x1; x <= x2; x += range) { - d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); - if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { - dminx = d; - mx = x; - } - } - - x = lastx; - for (y = y1; y <= y2; y += range) { - d = s->dsp.pix_abs[0][0](NULL, pix, ref_picture + (y * s->linesize) + x, s->linesize, 16); - if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { - dminy = d; - my = y; - } - } - - range = range >> 1; - - x = mx; - y = my; - x1 = mx - range; - if (x1 < xmin) - x1 = xmin; - - x2 = mx + range; - if (x2 > xmax) - x2 = xmax; - - y1 = my - range; - if (y1 < ymin) - y1 = ymin; - - y2 = my + range; - if (y2 > ymax) - y2 = ymax; - - } while (range >= 1); - -#ifdef DEBUG - av_log(s->avctx, AV_LOG_DEBUG, "phods - MX: %d\tMY: %d\n", mx, my); -#endif - - /* half pixel search */ - *mx_ptr = mx; - *my_ptr = my; - return dminy; -} -#endif /* 0 */ - #define Z_THRESHOLD 256 #define CHECK_SAD_HALF_MV(suffix, x, y) \ @@ -1225,23 +1002,6 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, my-= mb_y*16; dmin = 0; break; -#if 0 - case ME_FULL: - dmin = full_motion_search(s, &mx, &my, range, ref_picture); - mx-= mb_x*16; - my-= mb_y*16; - break; - case ME_LOG: - dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture); - mx-= mb_x*16; - my-= mb_y*16; - break; - case ME_PHODS: - dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture); - mx-= mb_x*16; - my-= mb_y*16; - break; -#endif case ME_X1: case ME_EPZS: { @@ -1513,23 +1273,6 @@ static int ff_estimate_motion_b(MpegEncContext * s, mx-= mb_x*16; my-= mb_y*16; break; -#if 0 - case ME_FULL: - dmin = full_motion_search(s, &mx, &my, range, ref_picture); - mx-= mb_x*16; - my-= mb_y*16; - break; - case ME_LOG: - dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture); - mx-= mb_x*16; - my-= mb_y*16; - break; - case ME_PHODS: - dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture); - mx-= mb_x*16; - my-= mb_y*16; - break; -#endif case ME_X1: case ME_EPZS: { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/motion_est_template.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/motion_est_template.c @@ -776,6 +776,41 @@ static int umh_search(MpegEncContext * s, int *best, int dmin, return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2); } +static int full_search(MpegEncContext * s, int *best, int dmin, + int src_index, int ref_index, int const penalty_factor, + int size, int h, int flags) +{ + MotionEstContext * const c= &s->me; + me_cmp_func cmpf, chroma_cmpf; + LOAD_COMMON + LOAD_COMMON2 + int map_generation= c->map_generation; + int x,y, d; + const int dia_size= c->dia_size&0xFF; + + cmpf= s->dsp.me_cmp[size]; + chroma_cmpf= s->dsp.me_cmp[size+1]; + + for(y=FFMAX(-dia_size, ymin); y<=FFMIN(dia_size,ymax); y++){ + for(x=FFMAX(-dia_size, xmin); x<=FFMIN(dia_size,xmax); x++){ + CHECK_MV(x, y); + } + } + + x= best[0]; + y= best[1]; + d= dmin; + CHECK_CLIPPED_MV(x , y); + CHECK_CLIPPED_MV(x+1, y); + CHECK_CLIPPED_MV(x, y+1); + CHECK_CLIPPED_MV(x-1, y); + CHECK_CLIPPED_MV(x, y-1); + best[0]= x; + best[1]= y; + + return d; +} + #define SAB_CHECK_MV(ax,ay)\ {\ const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\ @@ -980,6 +1015,8 @@ static av_always_inline int diamond_search(MpegEncContext * s, int *best, int dm return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); else if(c->dia_size<2) return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); + else if(c->dia_size>1024) + return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); else if(c->dia_size>768) return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); else if(c->dia_size>512) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/motionpixels.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/motionpixels.c @@ -0,0 +1,363 @@ +/* + * Motion Pixels Video Decoder + * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" + +#define MAX_HUFF_CODES 16 + +typedef struct YuvPixel { + int8_t y, v, u; +} YuvPixel; + +typedef struct HuffCode { + int code; + uint8_t size; + uint8_t delta; +} HuffCode; + +typedef struct MotionPixelsContext { + AVCodecContext *avctx; + AVFrame frame; + DSPContext dsp; + uint8_t *changes_map; + int offset_bits_len; + int codes_count, current_codes_count; + int max_codes_bits; + HuffCode codes[MAX_HUFF_CODES]; + VLC vlc; + YuvPixel *vpt, *hpt; + uint8_t gradient_scale[3]; + uint8_t *bswapbuf; + int bswapbuf_size; +} MotionPixelsContext; + +static YuvPixel mp_rgb_yuv_table[1 << 15]; + +static int mp_yuv_to_rgb(int y, int v, int u, int clip_rgb) { + static const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + int r, g, b; + + r = (1000 * y + 701 * v) / 1000; + g = (1000 * y - 357 * v - 172 * u) / 1000; + b = (1000 * y + 886 * u) / 1000; + if (clip_rgb) + return ((cm[r * 8] & 0xF8) << 7) | ((cm[g * 8] & 0xF8) << 2) | (cm[b * 8] >> 3); + if ((unsigned)r < 32 && (unsigned)g < 32 && (unsigned)b < 32) + return (r << 10) | (g << 5) | b; + return 1 << 15; +} + +static void mp_set_zero_yuv(YuvPixel *p) +{ + int i, j; + + for (i = 0; i < 31; ++i) { + for (j = 31; j > i; --j) + if (!(p[j].u | p[j].v | p[j].y)) + p[j] = p[j - 1]; + for (j = 0; j < 31 - i; ++j) + if (!(p[j].u | p[j].v | p[j].y)) + p[j] = p[j + 1]; + } +} + +static void mp_build_rgb_yuv_table(YuvPixel *p) +{ + int y, v, u, i; + + for (y = 0; y <= 31; ++y) + for (v = -31; v <= 31; ++v) + for (u = -31; u <= 31; ++u) { + i = mp_yuv_to_rgb(y, v, u, 0); + if (i < (1 << 15) && !(p[i].u | p[i].v | p[i].y)) { + p[i].y = y; + p[i].v = v; + p[i].u = u; + } + } + for (i = 0; i < 1024; ++i) + mp_set_zero_yuv(p + i * 32); +} + +static av_cold int mp_decode_init(AVCodecContext *avctx) +{ + MotionPixelsContext *mp = avctx->priv_data; + + if (!mp_rgb_yuv_table[0].u) { + mp_build_rgb_yuv_table(mp_rgb_yuv_table); + } + mp->avctx = avctx; + dsputil_init(&mp->dsp, avctx); + mp->changes_map = av_mallocz(avctx->width * avctx->height); + mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1; + mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel)); + mp->hpt = av_mallocz(avctx->height * avctx->width / 16 * sizeof(YuvPixel)); + return 0; +} + +static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int count, int bits_len, int read_color) +{ + uint16_t *pixels; + int offset, w, h, color = 0, x, y, i; + + while (count--) { + offset = get_bits_long(gb, mp->offset_bits_len); + w = get_bits(gb, bits_len) + 1; + h = get_bits(gb, bits_len) + 1; + if (read_color) + color = get_bits(gb, 15); + x = offset % mp->avctx->width; + y = offset / mp->avctx->width; + if (y >= mp->avctx->height) + continue; + w = FFMIN(w, mp->avctx->width - x); + h = FFMIN(h, mp->avctx->height - y); + pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; + while (h--) { + mp->changes_map[offset] = w; + if (read_color) + for (i = 0; i < w; ++i) + pixels[i] = color; + offset += mp->avctx->width; + pixels += mp->frame.linesize[0] / 2; + } + } +} + +static void mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code) +{ + while (get_bits1(gb)) { + ++size; + if (size > mp->max_codes_bits) { + av_log(mp->avctx, AV_LOG_ERROR, "invalid code size %d/%d\n", size, mp->max_codes_bits); + return; + } + code <<= 1; + mp_get_code(mp, gb, size, code + 1); + } + if (mp->current_codes_count >= MAX_HUFF_CODES) { + av_log(mp->avctx, AV_LOG_ERROR, "too many codes\n"); + return; + } + mp->codes[mp->current_codes_count ].code = code; + mp->codes[mp->current_codes_count++].size = size; +} + +static void mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb) +{ + if (mp->codes_count == 1) { + mp->codes[0].delta = get_bits(gb, 4); + } else { + int i; + + mp->max_codes_bits = get_bits(gb, 4); + for (i = 0; i < mp->codes_count; ++i) + mp->codes[i].delta = get_bits(gb, 4); + mp->current_codes_count = 0; + mp_get_code(mp, gb, 0, 0); + } +} + +static int mp_gradient(MotionPixelsContext *mp, int component, int v) +{ + int delta; + + delta = (v - 7) * mp->gradient_scale[component]; + mp->gradient_scale[component] = (v == 0 || v == 14) ? 2 : 1; + return delta; +} + +static YuvPixel mp_get_yuv_from_rgb(MotionPixelsContext *mp, int x, int y) +{ + int color; + + color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; + return mp_rgb_yuv_table[color]; +} + +static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const YuvPixel *p) +{ + int color; + + color = mp_yuv_to_rgb(p->y, p->v, p->u, 1); + *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color; +} + +static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) +{ + int i; + + i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1); + return mp->codes[i].delta; +} + +static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) +{ + YuvPixel p; + const int y0 = y * mp->avctx->width; + int w, i, x = 0; + + p = mp->vpt[y]; + if (mp->changes_map[y0 + x] == 0) { + memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); + ++x; + } + while (x < mp->avctx->width) { + w = mp->changes_map[y0 + x]; + if (w != 0) { + if ((y & 3) == 0) { + if (mp->changes_map[y0 + x + mp->avctx->width] < w || + mp->changes_map[y0 + x + mp->avctx->width * 2] < w || + mp->changes_map[y0 + x + mp->avctx->width * 3] < w) { + for (i = (x + 3) & ~3; i < x + w; i += 4) { + mp->hpt[((y / 4) * mp->avctx->width + i) / 4] = mp_get_yuv_from_rgb(mp, i, y); + } + } + } + x += w; + memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); + p = mp_get_yuv_from_rgb(mp, x - 1, y); + } else { + p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + if ((x & 3) == 0) { + if ((y & 3) == 0) { + p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p; + } else { + p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v; + p.u = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].u; + } + } + mp_set_rgb_from_yuv(mp, x, y, &p); + ++x; + } + } +} + +static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) +{ + YuvPixel p; + int y, y0; + + for (y = 0; y < mp->avctx->height; ++y) { + if (mp->changes_map[y * mp->avctx->width] != 0) { + memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); + p = mp_get_yuv_from_rgb(mp, 0, y); + } else { + p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + if ((y & 3) == 0) { + p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + } + mp->vpt[y] = p; + mp_set_rgb_from_yuv(mp, 0, y, &p); + } + } + for (y0 = 0; y0 < 2; ++y0) + for (y = y0; y < mp->avctx->height; y += 2) + mp_decode_line(mp, gb, y); +} + +static int mp_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + MotionPixelsContext *mp = avctx->priv_data; + GetBitContext gb; + int i, count1, count2, sz; + + mp->frame.reference = 1; + mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &mp->frame)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + /* le32 bitstream msb first */ + mp->bswapbuf = av_fast_realloc(mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); + if (buf_size & 3) + memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); + init_get_bits(&gb, mp->bswapbuf, buf_size * 8); + + memset(mp->changes_map, 0, avctx->width * avctx->height); + for (i = !(avctx->extradata[1] & 2); i < 2; ++i) { + count1 = get_bits(&gb, 12); + count2 = get_bits(&gb, 12); + mp_read_changes_map(mp, &gb, count1, 8, i); + mp_read_changes_map(mp, &gb, count2, 4, i); + } + + mp->codes_count = get_bits(&gb, 4); + if (mp->codes_count == 0) + goto end; + + if (mp->changes_map[0] == 0) { + *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15); + mp->changes_map[0] = 1; + } + mp_read_codes_table(mp, &gb); + + sz = get_bits(&gb, 18); + if (avctx->extradata[0] != 5) + sz += get_bits(&gb, 18); + if (sz == 0) + goto end; + + init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0); + mp_decode_frame_helper(mp, &gb); + free_vlc(&mp->vlc); + +end: + *data_size = sizeof(AVFrame); + *(AVFrame *)data = mp->frame; + return buf_size; +} + +static av_cold int mp_decode_end(AVCodecContext *avctx) +{ + MotionPixelsContext *mp = avctx->priv_data; + + av_freep(&mp->changes_map); + av_freep(&mp->vpt); + av_freep(&mp->hpt); + av_freep(&mp->bswapbuf); + if (mp->frame.data[0]) + avctx->release_buffer(avctx, &mp->frame); + + return 0; +} + +AVCodec motionpixels_decoder = { + "motionpixels", + CODEC_TYPE_VIDEO, + CODEC_ID_MOTIONPIXELS, + sizeof(MotionPixelsContext), + mp_decode_init, + NULL, + mp_decode_end, + mp_decode_frame, + CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels Video"), +}; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpeg12decdata.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpeg12decdata.h @@ -114,7 +114,7 @@ static const uint8_t mpeg2_dc_scale_table3[128]={ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; -static const uint8_t *mpeg2_dc_scale_table[4]={ +static const uint8_t * const mpeg2_dc_scale_table[4]={ ff_mpeg1_dc_scale_table, mpeg2_dc_scale_table1, mpeg2_dc_scale_table2, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpeg12enc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpeg12enc.c @@ -184,7 +184,7 @@ static void put_header(MpegEncContext *s, int header) { align_put_bits(&s->pb); put_bits(&s->pb, 16, header>>16); - put_bits(&s->pb, 16, header&0xFFFF); + put_sbits(&s->pb, 16, header); } /* put sequence header if needed */ @@ -206,8 +206,8 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) /* mpeg1 header repeated every gop */ put_header(s, SEQ_START_CODE); - put_bits(&s->pb, 12, s->width); - put_bits(&s->pb, 12, s->height); + put_sbits(&s->pb, 12, s->width ); + put_sbits(&s->pb, 12, s->height); for(i=1; i<15; i++){ float error= aspect_ratio; @@ -242,9 +242,9 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; vbv_buffer_size= (vbv_buffer_size + 16383) / 16384; - put_bits(&s->pb, 18, v & 0x3FFFF); + put_sbits(&s->pb, 18, v); put_bits(&s->pb, 1, 1); /* marker */ - put_bits(&s->pb, 10, vbv_buffer_size & 0x3FF); + put_sbits(&s->pb, 10, vbv_buffer_size); constraint_parameter_flag= s->width <= 768 && s->height <= 576 && @@ -272,8 +272,8 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) put_bits(&s->pb, 1, s->progressive_sequence); put_bits(&s->pb, 2, s->chroma_format); - put_bits(&s->pb, 2, 0); //horizontal size ext - put_bits(&s->pb, 2, 0); //vertical size ext + put_bits(&s->pb, 2, s->width >>12); + put_bits(&s->pb, 2, s->height>>12); put_bits(&s->pb, 12, v>>18); //bitrate ext put_bits(&s->pb, 1, 1); //marker put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext @@ -557,7 +557,7 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); } else { put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); - put_bits(&s->pb, 2, cbp & 3); + put_sbits(&s->pb, 2, cbp); } } s->f_count++; @@ -640,7 +640,7 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); } else { put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); - put_bits(&s->pb, 2, cbp & 3); + put_sbits(&s->pb, 2, cbp); } } } @@ -908,16 +908,16 @@ static void mpeg1_encode_block(MpegEncContext *s, put_bits(&s->pb, 6, run); if(s->codec_id == CODEC_ID_MPEG1VIDEO){ if (alevel < 128) { - put_bits(&s->pb, 8, level & 0xff); + put_sbits(&s->pb, 8, level); } else { if (level < 0) { put_bits(&s->pb, 16, 0x8001 + level + 255); } else { - put_bits(&s->pb, 16, level & 0xffff); + put_sbits(&s->pb, 16, level); } } }else{ - put_bits(&s->pb, 12, level & 0xfff); + put_sbits(&s->pb, 12, level); } } last_non_zero = i; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpegaudiodata.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpegaudiodata.c @@ -221,5 +221,5 @@ static const unsigned char alloc_table_4[] = { 2, 0, 1, 3, }; -const unsigned char *ff_mpa_alloc_tables[5] = +const unsigned char * const ff_mpa_alloc_tables[5] = { alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpegaudiodata.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpegaudiodata.h @@ -38,6 +38,6 @@ extern const int32_t ff_mpa_enwindow[257]; extern const int ff_mpa_sblimit_table[5]; extern const int ff_mpa_quant_steps[17]; extern const int ff_mpa_quant_bits[17]; -extern const unsigned char *ff_mpa_alloc_tables[5]; +extern const unsigned char * const ff_mpa_alloc_tables[5]; #endif /* FFMPEG_MPEGAUDIODATA_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpegaudiodec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/mpegaudiodec.c @@ -766,6 +766,8 @@ static inline int round_sample(int *sum) /* signed 16x16 -> 32 multiply */ #define MULS(ra, rb) MUL16(ra, rb) +#define MLSS(rt, ra, rb) MLS16(rt, ra, rb) + #else static inline int round_sample(int64_t *sum) @@ -781,47 +783,49 @@ static inline int round_sample(int64_t *sum) } # define MULS(ra, rb) MUL64(ra, rb) +# define MACS(rt, ra, rb) MAC64(rt, ra, rb) +# define MLSS(rt, ra, rb) MLS64(rt, ra, rb) #endif -#define SUM8(sum, op, w, p) \ -{ \ - sum op MULS((w)[0 * 64], p[0 * 64]);\ - sum op MULS((w)[1 * 64], p[1 * 64]);\ - sum op MULS((w)[2 * 64], p[2 * 64]);\ - sum op MULS((w)[3 * 64], p[3 * 64]);\ - sum op MULS((w)[4 * 64], p[4 * 64]);\ - sum op MULS((w)[5 * 64], p[5 * 64]);\ - sum op MULS((w)[6 * 64], p[6 * 64]);\ - sum op MULS((w)[7 * 64], p[7 * 64]);\ +#define SUM8(op, sum, w, p) \ +{ \ + op(sum, (w)[0 * 64], p[0 * 64]); \ + op(sum, (w)[1 * 64], p[1 * 64]); \ + op(sum, (w)[2 * 64], p[2 * 64]); \ + op(sum, (w)[3 * 64], p[3 * 64]); \ + op(sum, (w)[4 * 64], p[4 * 64]); \ + op(sum, (w)[5 * 64], p[5 * 64]); \ + op(sum, (w)[6 * 64], p[6 * 64]); \ + op(sum, (w)[7 * 64], p[7 * 64]); \ } #define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \ { \ int tmp;\ tmp = p[0 * 64];\ - sum1 op1 MULS((w1)[0 * 64], tmp);\ - sum2 op2 MULS((w2)[0 * 64], tmp);\ + op1(sum1, (w1)[0 * 64], tmp);\ + op2(sum2, (w2)[0 * 64], tmp);\ tmp = p[1 * 64];\ - sum1 op1 MULS((w1)[1 * 64], tmp);\ - sum2 op2 MULS((w2)[1 * 64], tmp);\ + op1(sum1, (w1)[1 * 64], tmp);\ + op2(sum2, (w2)[1 * 64], tmp);\ tmp = p[2 * 64];\ - sum1 op1 MULS((w1)[2 * 64], tmp);\ - sum2 op2 MULS((w2)[2 * 64], tmp);\ + op1(sum1, (w1)[2 * 64], tmp);\ + op2(sum2, (w2)[2 * 64], tmp);\ tmp = p[3 * 64];\ - sum1 op1 MULS((w1)[3 * 64], tmp);\ - sum2 op2 MULS((w2)[3 * 64], tmp);\ + op1(sum1, (w1)[3 * 64], tmp);\ + op2(sum2, (w2)[3 * 64], tmp);\ tmp = p[4 * 64];\ - sum1 op1 MULS((w1)[4 * 64], tmp);\ - sum2 op2 MULS((w2)[4 * 64], tmp);\ + op1(sum1, (w1)[4 * 64], tmp);\ + op2(sum2, (w2)[4 * 64], tmp);\ tmp = p[5 * 64];\ - sum1 op1 MULS((w1)[5 * 64], tmp);\ - sum2 op2 MULS((w2)[5 * 64], tmp);\ + op1(sum1, (w1)[5 * 64], tmp);\ + op2(sum2, (w2)[5 * 64], tmp);\ tmp = p[6 * 64];\ - sum1 op1 MULS((w1)[6 * 64], tmp);\ - sum2 op2 MULS((w2)[6 * 64], tmp);\ + op1(sum1, (w1)[6 * 64], tmp);\ + op2(sum2, (w2)[6 * 64], tmp);\ tmp = p[7 * 64];\ - sum1 op1 MULS((w1)[7 * 64], tmp);\ - sum2 op2 MULS((w2)[7 * 64], tmp);\ + op1(sum1, (w1)[7 * 64], tmp);\ + op2(sum2, (w2)[7 * 64], tmp);\ } void ff_mpa_synth_init(MPA_INT *window) @@ -885,9 +889,9 @@ void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, sum = *dither_state; p = synth_buf + 16; - SUM8(sum, +=, w, p); + SUM8(MACS, sum, w, p); p = synth_buf + 48; - SUM8(sum, -=, w + 32, p); + SUM8(MLSS, sum, w + 32, p); *samples = round_sample(&sum); samples += incr; w++; @@ -897,9 +901,9 @@ void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, for(j=1;j<16;j++) { sum2 = 0; p = synth_buf + 16 + j; - SUM8P2(sum, +=, sum2, -=, w, w2, p); + SUM8P2(sum, MACS, sum2, MLSS, w, w2, p); p = synth_buf + 48 - j; - SUM8P2(sum, -=, sum2, -=, w + 32, w2 + 32, p); + SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p); *samples = round_sample(&sum); samples += incr; @@ -911,7 +915,7 @@ void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, } p = synth_buf + 32; - SUM8(sum, -=, w + 32, p); + SUM8(MLSS, sum, w + 32, p); *samples = round_sample(&sum); *dither_state= sum; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/msmpeg4.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/msmpeg4.c @@ -98,7 +98,7 @@ static void common_init(MpegEncContext * s) case 3: if(s->workaround_bugs){ s->y_dc_scale_table= old_ff_y_dc_scale_table; - s->c_dc_scale_table= old_ff_c_dc_scale_table; + s->c_dc_scale_table= wmv1_c_dc_scale_table; } else{ s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; @@ -957,7 +957,7 @@ else put_bits(&s->pb, s->esc3_level_length, level); }else{ put_bits(&s->pb, 6, run); - put_bits(&s->pb, 8, slevel & 0xff); + put_sbits(&s->pb, 8, slevel); } } else { /* second escape */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/msmpeg4data.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/msmpeg4data.c @@ -1823,10 +1823,6 @@ const uint8_t old_ff_y_dc_scale_table[32]={ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 }; -const uint8_t old_ff_c_dc_scale_table[32]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 -}; const uint8_t wmv1_scantable[WMV1_SCANTABLE_COUNT][64]={ { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/msmpeg4data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/msmpeg4data.h @@ -76,7 +76,6 @@ extern RLTable rl_table[NB_RL_TABLES]; extern const uint8_t wmv1_y_dc_scale_table[32]; extern const uint8_t wmv1_c_dc_scale_table[32]; extern const uint8_t old_ff_y_dc_scale_table[32]; -extern const uint8_t old_ff_c_dc_scale_table[32]; extern MVTable mv_tables[2]; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/nellymoser.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/nellymoser.c @@ -147,7 +147,6 @@ void ff_nelly_get_sample_bits(const float *buf, int *bits) bitsum = sum_bits(sbuf, shift_saved, small_off); if (bitsum != NELLY_DETAIL_BITS) { - shift = 0; off = bitsum - NELLY_DETAIL_BITS; for(shift=0; FFABS(off) <= 16383; shift++) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/nellymoserdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/nellymoserdec.c @@ -130,7 +130,6 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, static av_cold int decode_init(AVCodecContext * avctx) { NellyMoserDecodeContext *s = avctx->priv_data; - int i; s->avctx = avctx; av_init_random(0, &s->random_state); @@ -148,9 +147,7 @@ static av_cold int decode_init(AVCodecContext * avctx) { /* Generate overlap window */ if (!sine_window[0]) - for (i=0 ; i<128; i++) { - sine_window[i] = sin((i + 0.5) / 256.0 * M_PI); - } + ff_sine_window_init(sine_window, 128); return 0; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/opt.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/opt.c @@ -94,14 +94,14 @@ static const AVOption *set_all_opt(void *v, const char *unit, double d){ return ret; } -static double const_values[]={ +static const double const_values[]={ M_PI, M_E, FF_QP2LAMBDA, 0 }; -static const char *const_names[]={ +static const char * const const_names[]={ "PI", "E", "QP2LAMBDA", @@ -115,7 +115,7 @@ static int hexchar2int(char c) { return -1; } -const AVOption *av_set_string(void *obj, const char *name, const char *val){ +const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){ const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ return set_all_opt(obj, o->unit, o->default_val); @@ -195,10 +195,19 @@ const AVOption *av_set_string(void *obj, const char *name, const char *val){ return NULL; } + if(alloc){ + av_free(*(void**)(((uint8_t*)obj) + o->offset)); + val= av_strdup(val); + } + memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); return o; } +const AVOption *av_set_string(void *obj, const char *name, const char *val){ + return av_set_string2(obj, name, val, 0); +} + const AVOption *av_set_double(void *obj, const char *name, double n){ return av_set_number(obj, name, n, 1, 1); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/opt.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/opt.h @@ -52,12 +52,20 @@ typedef struct AVOption { * @todo What about other languages? */ const char *help; - int offset; ///< offset to context structure where the parsed value should be stored + + /** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + */ + int offset; enum AVOptionType type; + /** + * the default value for scalar options + */ double default_val; - double min; - double max; + double min; ///< minimum valid value for the option + double max; ///< maximum valid value for the option int flags; #define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding @@ -67,12 +75,40 @@ typedef struct AVOption { #define AV_OPT_FLAG_VIDEO_PARAM 16 #define AV_OPT_FLAG_SUBTITLE_PARAM 32 //FIXME think about enc-audio, ... style flags + + /** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + */ const char *unit; } AVOption; +/** + * Looks for an option in \p obj. Looks only for the options which + * have the flags set as specified in \p mask and \p flags (that is, + * for which it is the case that opt->flags & mask == flags). + * + * @param[in] obj a pointer to a struct whose first element is a + * pointer to an #AVClass + * @param[in] name the name of the option to look for + * @param[in] unit the unit of the option to look for, or any if NULL + * @return a pointer to the option found, or NULL if no option + * has been found + */ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags); -const AVOption *av_set_string(void *obj, const char *name, const char *val); + +attribute_deprecated const AVOption *av_set_string(void *obj, const char *name, const char *val); + +/** + * Sets the field of obj with the given name to value. + * @param alloc when 1 then the old value will be av_freed() and the + * new av_strduped() + * when 0 then no av_free() nor av_strdup() will be used + */ +const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc); + const AVOption *av_set_double(void *obj, const char *name, double n); const AVOption *av_set_q(void *obj, const char *name, AVRational n); const AVOption *av_set_int(void *obj, const char *name, int64_t n); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/pcm.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/pcm.c @@ -556,6 +556,7 @@ AVCodec name ## _decoder = { \ #define PCM_CODEC(id, name, long_name_) \ PCM_ENCODER(id,name,long_name_) PCM_DECODER(id,name,long_name_) +/* Note: Do not forget to add new entries to the Makefile as well. */ PCM_CODEC (CODEC_ID_PCM_ALAW, pcm_alaw, "A-law PCM"); PCM_CODEC (CODEC_ID_PCM_DVD, pcm_dvd, "signed 16|20|24-bit big-endian PCM"); PCM_CODEC (CODEC_ID_PCM_MULAW, pcm_mulaw, "mu-law PCM"); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/pngdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/pngdec.c @@ -383,7 +383,7 @@ static int decode_frame(AVCodecContext *avctx, { PNGDecContext * const s = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p= &s->picture; uint32_t tag, length; int ret, crc; @@ -582,8 +582,8 @@ static int decode_frame(AVCodecContext *avctx, } } exit_loop: - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); + *picture= s->picture; + *data_size = sizeof(AVFrame); ret = s->bytestream - s->bytestream_start; the_end: @@ -600,8 +600,8 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int png_dec_init(AVCodecContext *avctx){ PNGDecContext *s = avctx->priv_data; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame= &s->picture; dsputil_init(&s->dsp, avctx); return 0; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/pngenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/pngenc.c @@ -232,7 +232,7 @@ static int png_write_row(PNGEncContext *s, const uint8_t *data, int size) static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ PNGEncContext *s = avctx->priv_data; AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p= &s->picture; int bit_depth, color_type, y, len, row_size, ret, is_progressive; int bits_per_pixel, pass_row_size; int compression_level; @@ -425,8 +425,8 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, static av_cold int png_enc_init(AVCodecContext *avctx){ PNGEncContext *s = avctx->priv_data; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame= &s->picture; dsputil_init(&s->dsp, avctx); s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ppc/fdct_altivec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ppc/fdct_altivec.c @@ -58,9 +58,9 @@ static vector float fdctconsts[3] = { - (vector float)AVV( W0, W1, W2, W3 ), - (vector float)AVV( W4, W5, W6, W7 ), - (vector float)AVV( W8, W9, WA, WB ) + AVV( W0, W1, W2, W3 ), + AVV( W4, W5, W6, W7 ), + AVV( W8, W9, WA, WB ) }; #define LD_W0 vec_splat(cnsts0, 0) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ppc/idct_altivec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ppc/idct_altivec.c @@ -158,11 +158,11 @@ static const_vector_s16_t constants[5] = { - (vector_s16_t) AVV(23170, 13573, 6518, 21895, -23170, -21895, 32, 31), - (vector_s16_t) AVV(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725), - (vector_s16_t) AVV(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521), - (vector_s16_t) AVV(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692), - (vector_s16_t) AVV(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722) + AVV(23170, 13573, 6518, 21895, -23170, -21895, 32, 31), + AVV(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725), + AVV(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521), + AVV(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692), + AVV(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722) }; void idct_put_altivec(uint8_t* dest, int stride, vector_s16_t* block) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ppc/int_altivec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ppc/int_altivec.c @@ -29,6 +29,8 @@ #include "dsputil_altivec.h" +#include "types_altivec.h" + static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2, int size) { int i, size16; @@ -74,7 +76,68 @@ static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2, return u.score[3]; } +static void add_int16_altivec(int16_t * v1, int16_t * v2, int order) +{ + int i; + register vec_s16_t vec, *pv; + + for(i = 0; i < order; i += 8){ + pv = (vec_s16_t*)v2; + vec = vec_perm(pv[0], pv[1], vec_lvsl(0, v2)); + vec_st(vec_add(vec_ld(0, v1), vec), 0, v1); + v1 += 8; + v2 += 8; + } +} + +static void sub_int16_altivec(int16_t * v1, int16_t * v2, int order) +{ + int i; + register vec_s16_t vec, *pv; + + for(i = 0; i < order; i += 8){ + pv = (vec_s16_t*)v2; + vec = vec_perm(pv[0], pv[1], vec_lvsl(0, v2)); + vec_st(vec_sub(vec_ld(0, v1), vec), 0, v1); + v1 += 8; + v2 += 8; + } +} + +static int32_t scalarproduct_int16_altivec(int16_t * v1, int16_t * v2, int order, const int shift) +{ + int i; + LOAD_ZERO; + register vec_s16_t vec1, *pv; + register vec_s32_t res = vec_splat_s32(0), t; + register vec_u32_t shifts; + DECLARE_ALIGNED_16(int32_t, ires); + + shifts = zero_u32v; + if(shift & 0x10) shifts = vec_add(shifts, vec_sl(vec_splat_u32(0x08), vec_splat_u32(0x1))); + if(shift & 0x08) shifts = vec_add(shifts, vec_splat_u32(0x08)); + if(shift & 0x04) shifts = vec_add(shifts, vec_splat_u32(0x04)); + if(shift & 0x02) shifts = vec_add(shifts, vec_splat_u32(0x02)); + if(shift & 0x01) shifts = vec_add(shifts, vec_splat_u32(0x01)); + + for(i = 0; i < order; i += 8){ + pv = (vec_s16_t*)v1; + vec1 = vec_perm(pv[0], pv[1], vec_lvsl(0, v1)); + t = vec_msum(vec1, vec_ld(0, v2), zero_s32v); + t = vec_sr(t, shifts); + res = vec_sums(t, res); + v1 += 8; + v2 += 8; + } + res = vec_splat(res, 3); + vec_ste(res, 0, &ires); + return ires; +} + void int_init_altivec(DSPContext* c, AVCodecContext *avctx) { c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec; + c->add_int16 = add_int16_altivec; + c->sub_int16 = sub_int16_altivec; + c->scalarproduct_int16 = scalarproduct_int16_altivec; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/qdm2.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/qdm2.c @@ -361,7 +361,7 @@ static void qdm2_init_vlc(void) /* for floating point to fixed point conversion */ -static float f2i_scale = (float) (1 << (FRAC_BITS - 15)); +static const float f2i_scale = (float) (1 << (FRAC_BITS - 15)); static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) @@ -684,7 +684,7 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra SAMPLES_NEEDED for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) { - for (j = 1; j < 64; j++) { + for (j = 1; j < 63; j++) { // The loop only iterates to 63 so the code doesn't overflow the buffer add1 = tone_level_idx[ch][sb][j] - 10; if (add1 < 0) add1 = 0; @@ -1438,10 +1438,10 @@ static void qdm2_decode_fft_packets (QDM2Context *q) /* process subpackets ordered by type, largest type first */ for (i = 0, max = 256; i < q->sub_packets_B; i++) { - QDM2SubPacket *packet; + QDM2SubPacket *packet= NULL; /* find subpacket with largest type less than max */ - for (j = 0, min = 0, packet = NULL; j < q->sub_packets_B; j++) { + for (j = 0, min = 0; j < q->sub_packets_B; j++) { value = q->sub_packet_list_B[j].packet->type; if (value > min && value < max) { min = value; @@ -1452,6 +1452,9 @@ static void qdm2_decode_fft_packets (QDM2Context *q) max = min; /* check for errors (?) */ + if (!packet) + return; + if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16])) return; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/qdm2data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/qdm2data.h @@ -254,17 +254,17 @@ static const int16_t fft_level_index_table[256] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, }; -static uint8_t last_coeff[3] = { +static const uint8_t last_coeff[3] = { 4, 7, 10 }; -static uint8_t coeff_per_sb_for_avg[3][30] = { +static const uint8_t coeff_per_sb_for_avg[3][30] = { { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, { 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9 } }; -static uint32_t dequant_table[3][10][30] = { +static const uint32_t dequant_table[3][10][30] = { { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 256, 256, 205, 154, 102, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 51, 102, 154, 205, 256, 238, 219, 201, 183, 165, 146, 128, 110, 91, 73, 55, 37, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -297,14 +297,14 @@ static uint32_t dequant_table[3][10][30] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 85, 128, 171, 213, 256, 213, 171, 128, 85, 43 } } }; -static uint8_t coeff_per_sb_for_dequant[3][30] = { +static const uint8_t coeff_per_sb_for_dequant[3][30] = { { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, { 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 }, { 0, 1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9 } }; /* first index is subband, 2nd index is 0, 1 or 3 (2 is unused) */ -static int8_t tone_level_idx_offset_table[30][4] = { +static const int8_t tone_level_idx_offset_table[30][4] = { { -50, -50, 0, -50 }, { -50, -50, 0, -50 }, { -50, -9, 0, -19 }, @@ -339,7 +339,7 @@ static int8_t tone_level_idx_offset_table[30][4] = { /* all my samples have 1st index 0 or 1 */ /* second index is subband, only indexes 0-29 seem to be used */ -static int8_t coding_method_table[5][30] = { +static const int8_t coding_method_table[5][30] = { { 34, 30, 24, 24, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }, @@ -513,7 +513,7 @@ static const uint8_t fft_subpackets[32] = { }; /* first index is joined_stereo, second index is 0 or 2 (1 is unused) */ -static float dequant_1bit[2][3] = { +static const float dequant_1bit[2][3] = { {-0.920000f, 0.000000f, 0.920000f }, {-0.890000f, 0.000000f, 0.890000f } }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/qpeg.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/qpeg.c @@ -108,9 +108,9 @@ static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, } } -static int qpeg_table_h[16] = +static const int qpeg_table_h[16] = { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04}; -static int qpeg_table_w[16] = +static const int qpeg_table_w[16] = { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; /* Decodes delta frames */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra144.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra144.c @@ -1,6 +1,9 @@ /* * Real Audio 1.0 (14.4K) - * Copyright (c) 2003 the ffmpeg project + * + * Copyright (c) 2008 Vitor Sessak + * Copyright (c) 2003 Nick Kurshev + * Based on public domain decoder at http://www.honeypot.net/audio * * This file is part of FFmpeg. * @@ -22,33 +25,38 @@ #include "avcodec.h" #include "bitstream.h" #include "ra144.h" +#include "acelp_filters.h" -#define NBLOCKS 4 /* number of segments within a block */ -#define BLOCKSIZE 40 /* (quarter) block size in 16-bit words (80 bytes) */ -#define HALFBLOCK 20 /* BLOCKSIZE/2 */ -#define BUFFERSIZE 146 /* for do_output */ +#define NBLOCKS 4 ///< number of subblocks within a block +#define BLOCKSIZE 40 ///< subblock size in 16-bit words +#define BUFFERSIZE 146 ///< the size of the adaptive codebook typedef struct { unsigned int old_energy; ///< previous frame energy - /* the swapped buffers */ unsigned int lpc_tables[2][10]; - unsigned int *lpc_coef; ///< LPC coefficients - unsigned int *lpc_coef_old; ///< previous frame LPC coefficients - unsigned int lpc_refl_rms; - unsigned int lpc_refl_rms_old; - unsigned int buffer[5]; - uint16_t adapt_cb[148]; ///< adaptive codebook + /** LPC coefficients: lpc_coef[0] is the coefficients of the current frame + * and lpc_coef[1] of the previous one */ + unsigned int *lpc_coef[2]; + + unsigned int lpc_refl_rms[2]; + + /** the current subblock padded by the last 10 values of the previous one*/ + int16_t curr_sblock[50]; + + /** adaptive codebook. Its size is two units bigger to avoid a + * buffer overflow */ + uint16_t adapt_cb[148]; } RA144Context; static int ra144_decode_init(AVCodecContext * avctx) { RA144Context *ractx = avctx->priv_data; - ractx->lpc_coef = ractx->lpc_tables[0]; - ractx->lpc_coef_old = ractx->lpc_tables[1]; + ractx->lpc_coef[0] = ractx->lpc_tables[0]; + ractx->lpc_coef[1] = ractx->lpc_tables[1]; return 0; } @@ -59,20 +67,20 @@ static int ra144_decode_init(AVCodecContext * avctx) */ static int t_sqrt(unsigned int x) { - int s = 0; + int s = 2; while (x > 0xfff) { s++; x = x >> 2; } - return (ff_sqrt(x << 20) << s) << 2; + return ff_sqrt(x << 20) << s; } /** * Evaluate the LPC filter coefficients from the reflection coefficients. * Does the inverse of the eval_refl() function. */ -static void eval_coefs(const int *refl, int *coefs) +static void eval_coefs(int *coefs, const int *refl) { int buffer[10]; int *b1 = buffer; @@ -92,22 +100,24 @@ static void eval_coefs(const int *refl, int *coefs) coefs[x] >>= 4; } -/* rotate block */ -static void rotate_block(const int16_t *source, int16_t *target, int offset) +/** + * Copy the last offset values of *source to *target. If those values are not + * enough to fill the target buffer, fill it with another copy of those values. + */ +static void copy_and_dup(int16_t *target, const int16_t *source, int offset) { - int i=0, k=0; source += BUFFERSIZE - offset; - while (i<BLOCKSIZE) { - target[i++] = source[k++]; - - if (k == offset) - k = 0; + if (offset > BLOCKSIZE) { + memcpy(target, source, BLOCKSIZE*sizeof(*target)); + } else { + memcpy(target, source, offset*sizeof(*target)); + memcpy(target + offset, source, (BLOCKSIZE - offset)*sizeof(*target)); } } -/* inverse root mean square */ -static int irms(const int16_t *data, int factor) +/** inverse root mean square */ +static int irms(const int16_t *data) { unsigned int i, sum = 0; @@ -117,12 +127,11 @@ static int irms(const int16_t *data, int factor) if (sum == 0) return 0; /* OOPS - division by zero */ - return (0x20000000 / (t_sqrt(sum) >> 8)) * factor; + return 0x20000000 / (t_sqrt(sum) >> 8); } -/* multiply/add wavetable */ -static void add_wav(int n, int skip_first, int *m, const int16_t *s1, - const int8_t *s2, const int8_t *s3, int16_t *dest) +static void add_wav(int16_t *dest, int n, int skip_first, int *m, + const int16_t *s1, const int8_t *s2, const int8_t *s3) { int i; int v[3]; @@ -132,45 +141,10 @@ static void add_wav(int n, int skip_first, int *m, const int16_t *s1, v[i] = (gain_val_tab[n][i] * m[i]) >> (gain_exp_tab[n][i] + 1); for (i=0; i < BLOCKSIZE; i++) - dest[i] = ((*(s1++))*v[0] + (*(s2++))*v[1] + (*(s3++))*v[2]) >> 12; -} - -static void lpc_filter(const int16_t *lpc_coefs, const int16_t *adapt_coef, - void *out, int *statbuf, int len) -{ - int x, i; - uint16_t work[50]; - int16_t *ptr = work; - - memcpy(work, statbuf,20); - memcpy(work + 10, adapt_coef, len * 2); - - for (i=0; i<len; i++) { - int sum = 0; - int new_val; - - for(x=0; x<10; x++) - sum += lpc_coefs[9-x] * ptr[x]; - - sum >>= 12; - - new_val = ptr[10] - sum; - - if (new_val < -32768 || new_val > 32767) { - memset(out, 0, len * 2); - memset(statbuf, 0, 20); - return; - } - - ptr[10] = new_val; - ptr++; - } - - memcpy(out, work+10, len * 2); - memcpy(statbuf, work + 40, 20); + dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12; } -static unsigned int rescale_rms(int rms, int energy) +static unsigned int rescale_rms(unsigned int rms, unsigned int energy) { return (rms * energy) >> 10; } @@ -182,7 +156,7 @@ static unsigned int rms(const int *data) int b = 0; for (x=0; x<10; x++) { - res = (((0x1000000 - (*data) * (*data)) >> 12) * res) >> 12; + res = (((0x1000000 - data[x]*data[x]) >> 12) * res) >> 12; if (res == 0) return 0; @@ -191,20 +165,16 @@ static unsigned int rms(const int *data) b++; res <<= 2; } - data++; } - if (res > 0) - res = t_sqrt(res); + res = t_sqrt(res); res >>= (b + 10); return res; } -/* do quarter-block output */ -static void do_output_subblock(RA144Context *ractx, - const uint16_t *lpc_coefs, unsigned int gval, - int16_t *output_buffer, GetBitContext *gb) +static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, + int gval, GetBitContext *gb) { uint16_t buffer_a[40]; uint16_t *block; @@ -215,25 +185,35 @@ static void do_output_subblock(RA144Context *ractx, int m[3]; if (cba_idx) { - cba_idx += HALFBLOCK - 1; - rotate_block(ractx->adapt_cb, buffer_a, cba_idx); - m[0] = irms(buffer_a, gval) >> 12; + cba_idx += BLOCKSIZE/2 - 1; + copy_and_dup(buffer_a, ractx->adapt_cb, cba_idx); + m[0] = (irms(buffer_a) * gval) >> 12; } else { m[0] = 0; } - m[1] = ((cb1_base[cb1_idx] >> 4) * gval) >> 8; - m[2] = ((cb2_base[cb2_idx] >> 4) * gval) >> 8; + m[1] = (cb1_base[cb1_idx] * gval) >> 8; + m[2] = (cb2_base[cb2_idx] * gval) >> 8; memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE, - (BUFFERSIZE - BLOCKSIZE) * 2); + (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb)); block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE; - add_wav(gain, cba_idx, m, buffer_a, cb1_vects[cb1_idx], cb2_vects[cb2_idx], - block); + add_wav(block, gain, cba_idx, m, buffer_a, + cb1_vects[cb1_idx], cb2_vects[cb2_idx]); - lpc_filter(lpc_coefs, block, output_buffer, ractx->buffer, BLOCKSIZE); + memcpy(ractx->curr_sblock, ractx->curr_sblock + 40, + 10*sizeof(*ractx->curr_sblock)); + memcpy(ractx->curr_sblock + 10, block, + BLOCKSIZE*sizeof(*ractx->curr_sblock)); + + if (ff_acelp_lp_synthesis_filter( + ractx->curr_sblock + 10, lpc_coefs, + ractx->curr_sblock + 10, BLOCKSIZE, + 10, 1, 0xfff) + ) + memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock)); } static void int_to_int16(int16_t *out, const int *inp) @@ -251,7 +231,7 @@ static void int_to_int16(int16_t *out, const int *inp) * @return 1 if one of the reflection coefficients is of magnitude greater than * 4095, 0 if not. */ -static int eval_refl(const int16_t *coefs, int *refl, RA144Context *ractx) +static int eval_refl(int *refl, const int16_t *coefs, RA144Context *ractx) { int retval = 0; int b, c, i; @@ -268,7 +248,7 @@ static int eval_refl(const int16_t *coefs, int *refl, RA144Context *ractx) if (u + 0x1000 > 0x1fff) { av_log(ractx, AV_LOG_ERROR, "Overflow. Broken sample?\n"); - return 0; + return 1; } for (c=8; c >= 0; c--) { @@ -297,7 +277,7 @@ static int eval_refl(const int16_t *coefs, int *refl, RA144Context *ractx) } static int interp(RA144Context *ractx, int16_t *out, int block_num, - int copynew, int energy) + int copyold, int energy) { int work[10]; int a = block_num + 1; @@ -307,27 +287,21 @@ static int interp(RA144Context *ractx, int16_t *out, int block_num, // Interpolate block coefficients from the this frame forth block and // last frame forth block for (x=0; x<30; x++) - out[x] = (a * ractx->lpc_coef[x] + b * ractx->lpc_coef_old[x])>> 2; + out[x] = (a * ractx->lpc_coef[0][x] + b * ractx->lpc_coef[1][x])>> 2; - if (eval_refl(out, work, ractx)) { + if (eval_refl(work, out, ractx)) { // The interpolated coefficients are unstable, copy either new or old // coefficients - if (copynew) { - int_to_int16(out, ractx->lpc_coef); - return rescale_rms(ractx->lpc_refl_rms, energy); - } else { - int_to_int16(out, ractx->lpc_coef_old); - return rescale_rms(ractx->lpc_refl_rms_old, energy); - } + int_to_int16(out, ractx->lpc_coef[copyold]); + return rescale_rms(ractx->lpc_refl_rms[copyold], energy); } else { return rescale_rms(rms(work), energy); } } -/* Uncompress one block (20 bytes -> 160*2 bytes) */ -static int ra144_decode_frame(AVCodecContext * avctx, - void *vdata, int *data_size, - const uint8_t * buf, int buf_size) +/** Uncompress one block (20 bytes -> 160*2 bytes) */ +static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, + int *data_size, const uint8_t *buf, int buf_size) { static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; unsigned int refl_rms[4]; // RMS of the reflection coefficients @@ -343,41 +317,38 @@ static int ra144_decode_frame(AVCodecContext * avctx, if(buf_size < 20) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); + *data_size = 0; return buf_size; } init_get_bits(&gb, buf, 20 * 8); for (i=0; i<10; i++) - // "<< 1"? Doesn't this make one value out of two of the table useless? - lpc_refl[i] = lpc_refl_cb[i][get_bits(&gb, sizes[i]) << 1]; + lpc_refl[i] = lpc_refl_cb[i][get_bits(&gb, sizes[i])]; - eval_coefs(lpc_refl, ractx->lpc_coef); - ractx->lpc_refl_rms = rms(lpc_refl); + eval_coefs(ractx->lpc_coef[0], lpc_refl); + ractx->lpc_refl_rms[0] = rms(lpc_refl); - energy = energy_tab[get_bits(&gb, 5) << 1]; // Useless table entries? + energy = energy_tab[get_bits(&gb, 5)]; - refl_rms[0] = interp(ractx, block_coefs[0], 0, 0, ractx->old_energy); - refl_rms[1] = interp(ractx, block_coefs[1], 1, energy > ractx->old_energy, + refl_rms[0] = interp(ractx, block_coefs[0], 0, 1, ractx->old_energy); + refl_rms[1] = interp(ractx, block_coefs[1], 1, energy <= ractx->old_energy, t_sqrt(energy*ractx->old_energy) >> 12); - refl_rms[2] = interp(ractx, block_coefs[2], 2, 1, energy); - refl_rms[3] = rescale_rms(ractx->lpc_refl_rms, energy); + refl_rms[2] = interp(ractx, block_coefs[2], 2, 0, energy); + refl_rms[3] = rescale_rms(ractx->lpc_refl_rms[0], energy); - int_to_int16(block_coefs[3], ractx->lpc_coef); + int_to_int16(block_coefs[3], ractx->lpc_coef[0]); - /* do output */ for (c=0; c<4; c++) { - do_output_subblock(ractx, block_coefs[c], refl_rms[c], data, &gb); + do_output_subblock(ractx, block_coefs[c], refl_rms[c], &gb); - for (i=0; i<BLOCKSIZE; i++) { - *data = av_clip_int16(*data << 2); - data++; - } + for (i=0; i<BLOCKSIZE; i++) + *data++ = av_clip_int16(ractx->curr_sblock[i + 10] << 2); } ractx->old_energy = energy; - ractx->lpc_refl_rms_old = ractx->lpc_refl_rms; + ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0]; - FFSWAP(unsigned int *, ractx->lpc_coef_old, ractx->lpc_coef); + FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); *data_size = 2*160; return 20; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra144.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra144.h @@ -25,522 +25,138 @@ #include <stdint.h> /* 14.4 data tables */ -static const int16_t gain_val_tab[256][9] = { - { 541, 956, 768, -1011, -811, -717, -571, -893, -576}, - { 877, 581, 568, -997, -975, -646, -752, -661, -632}, - { 675, 787, 635, -519, -838, -977, -890, -605, -789}, - { 624, 732, 668, -893, -815, -956, -762, -523, -873}, - { 623, 839, 697, -1022, -849, -571, -759, -688, -949}, - { 640, 693, 991, -867, -619, -671, -800, -940, -959}, - { 925, 687, 608, -621, -549, -817, -837, -924, -722}, - { 552, 797, 572, -861, -617, -892, -596, -621, -640}, - { 535, 832, 799, -871, -836, -649, -560, -676, -624}, - { 762, 605, 577, -902, -859, -682, -568, -716, -650}, - { 832, 561, 1003, -913, -815, -550, -676, -616, -982}, - { 590, 687, 588, -793, -679, -790, -681, -923, -677}, - { 646, 901, 732, -569, -924, -645, -816, -794, -524}, - { 828, 689, 896, -557, -725, -603, -670, -927, -784}, - { 875, 624, 848, -533, -725, -516, -748, -760, -702}, - { 571, 942, 1022, -526, -570, -941, -638, -868, -1020}, - { 824, 736, 643, -593, -517, -925, -663, -530, -808}, - { 517, 765, 512, -774, -518, -767, -523, -572, -513}, - { 562, 908, 761, -997, -836, -675, -617, -805, -566}, - { 694, 913, 675, -619, -916, -603, -941, -815, -891}, - { 704, 524, 672, -722, -925, -689, -969, -538, -883}, - { 721, 757, 558, -534, -786, -826, -1018, -561, -608}, - { 884, 551, 633, -951, -546, -681, -763, -592, -784}, - { 558, 1007, 846, -549, -923, -832, -608, -991, -699}, - { 932, 746, 777, -679, -707, -566, -849, -544, -589}, - { 566, 822, 926, -910, -513, -744, -627, -659, -839}, - { 613, 771, 611, -924, -731, -921, -733, -581, -729}, - { 737, 671, 1008, -967, -726, -661, -531, -880, -993}, - { 651, 594, 579, -757, -737, -673, -830, -691, -655}, - { 801, 636, 564, -996, -883, -702, -626, -792, -622}, - { 852, 910, 719, -757, -599, -639, -709, -809, -1012}, - { 998, 614, 575, -599, -561, -691, -974, -737, -647}, - { 665, 935, 628, -607, -816, -574, -863, -854, -771}, - { 631, 596, 829, -735, -1023, -966, -778, -694, -672}, - { 644, 926, 526, -583, -663, -953, -811, -838, -542}, - { 879, 988, 613, -848, -526, -592, -755, -953, -734}, - { 941, 692, 693, -637, -638, -939, -866, -937, -940}, - { 565, 672, 576, -742, -637, -757, -625, -882, -649}, - { 547, 628, 740, -671, -791, -909, -585, -771, -535}, - { 639, 532, 537, -665, -671, -559, -798, -554, -564}, - { 955, 604, 598, -564, -558, -706, -891, -714, -699}, - { 562, 580, 900, -637, -989, -1021, -617, -658, -791}, - { 603, 899, 621, -530, -733, -545, -712, -789, -755}, - { 746, 533, 624, -776, -909, -650, -543, -555, -761}, - { 729, 514, 735, -733, -523, -739, -519, -517, -528}, - { 853, 551, 692, -919, -577, -745, -711, -593, -936}, - { 949, 1018, 1004, -944, -931, -999, -880, -1013, -985}, - { 544, 988, 735, -525, -781, -710, -578, -954, -528}, - { 789, 782, 821, -603, -633, -628, -608, -598, -659}, - { 897, 516, 754, -906, -661, -761, -786, -521, -556}, - { 517, 702, 828, -710, -837, -568, -523, -963, -670}, - { 586, 818, 763, -937, -874, -609, -672, -654, -568}, - { 907, 652, 592, -578, -525, -754, -804, -830, -686}, - { 528, 652, 642, -673, -663, -818, -546, -830, -806}, - { 531, 708, 780, -736, -811, -540, -552, -981, -595}, - { 666, 625, 727, -813, -946, -888, -867, -763, -516}, - { 947, 727, 554, -673, -512, -787, -875, -517, -599}, - { 549, 657, 981, -705, -526, -630, -589, -843, -941}, - { 605, 920, 852, -544, -1008, -766, -716, -827, -709}, - { 624, 619, 983, -755, -599, -595, -761, -750, -944}, - { 605, 909, 547, -537, -646, -971, -715, -807, -584}, - { 690, 935, 516, -631, -697, -944, -932, -855, -521}, - { 700, 612, 853, -838, -584, -1021, -959, -732, -711}, - { 767, 832, 574, -623, -861, -933, -575, -676, -643}, - { 523, 898, 923, -919, -945, -810, -536, -789, -833}, - { 722, 958, 691, -676, -976, -647, -1020, -896, -935}, - { 613, 771, 928, -924, -556, -700, -734, -581, -842}, - { 758, 757, 584, -561, -866, -865, -562, -560, -667}, - { 512, 567, 577, -567, -577, -639, -512, -628, -650}, - { 615, 638, 698, -766, -839, -871, -739, -795, -954}, - { 574, 642, 589, -720, -660, -739, -644, -806, -677}, - { 993, 682, 878, -662, -852, -585, -963, -910, -753}, - { 539, 890, 913, -939, -963, -795, -569, -775, -815}, - { 694, 928, 544, -629, -738, -987, -941, -842, -578}, - { 805, 600, 680, -944, -535, -798, -633, -704, -905}, - { 540, 951, 782, -1004, -825, -727, -570, -884, -597}, - { 816, 950, 590, -757, -941, -548, -650, -881, -681}, - { 955, 847, 811, -790, -757, -671, -891, -700, -643}, - { 547, 883, 556, -945, -595, -960, -586, -762, -605}, - { 652, 888, 604, -565, -770, -524, -831, -770, -713}, - { 863, 585, 855, -986, -721, -978, -727, -668, -715}, - {1023, 997, 516, -997, -516, -1006, -1023, -972, -520}, - { 932, 614, 640, -560, -583, -769, -850, -738, -800}, - { 627, 564, 573, -691, -702, -631, -769, -621, -641}, - { 876, 900, 724, -770, -620, -637, -750, -792, -512}, - { 515, 857, 896, -863, -902, -750, -519, -718, -784}, - { 647, 953, 879, -602, -555, -818, -817, -888, -755}, - { 806, 854, 857, -672, -675, -715, -634, -712, -718}, - { 545, 583, 631, -621, -672, -719, -581, -664, -778}, - { 657, 601, 751, -772, -963, -882, -843, -707, -550}, - { 740, 905, 795, -654, -575, -704, -535, -801, -618}, - { 841, 1016, 568, -835, -934, -564, -691, -1009, -631}, - { 747, 589, 983, -861, -718, -566, -545, -679, -945}, - { 878, 613, 526, -526, -902, -630, -753, -736, -540}, - { 864, 723, 779, -610, -657, -550, -729, -1022, -592}, - { 534, 674, 774, -703, -808, -1019, -557, -887, -586}, - { 950, 649, 939, -602, -871, -595, -881, -824, -861}, - { 590, 703, 899, -811, -518, -618, -680, -966, -790}, - { 618, 527, 579, -637, -700, -597, -746, -543, -657}, - { 725, 647, 972, -917, -689, -615, -513, -818, -924}, - { 641, 647, 707, -810, -885, -893, -803, -817, -976}, - { 730, 663, 644, -946, -920, -835, -521, -860, -812}, - { 807, 572, 578, -902, -912, -646, -637, -639, -653}, - { 879, 611, 821, -524, -705, -979, -755, -729, -658}, - { 667, 729, 841, -951, -549, -599, -871, -519, -692}, - { 782, 585, 751, -895, -574, -859, -598, -670, -551}, - { 802, 733, 976, -574, -765, -699, -628, -525, -931}, - { 850, 871, 708, -724, -588, -602, -706, -742, -979}, - { 870, 743, 704, -632, -598, -1023, -739, -540, -970}, - { 941, 899, 585, -827, -538, -514, -866, -790, -669}, - { 943, 632, 875, -582, -806, -541, -869, -781, -749}, - {1023, 732, 638, -731, -637, -912, -1022, -523, -795}, - { 778, 753, 655, -573, -997, -965, -592, -554, -839}, - { 843, 945, 945, -779, -779, -873, -694, -873, -873}, - { 942, 969, 572, -892, -527, -542, -867, -918, -640}, - {1008, 559, 854, -551, -841, -934, -993, -612, -712}, - { 868, 729, 787, -618, -668, -560, -737, -519, -605}, - { 970, 686, 547, -650, -518, -733, -919, -919, -585}, - { 535, 635, 674, -664, -705, -836, -560, -788, -887}, - { 560, 636, 828, -696, -907, -514, -613, -790, -670}, - { 994, 592, 833, -575, -809, -964, -966, -686, -677}, - { 548, 621, 694, -665, -743, -843, -587, -755, -942}, - { 550, 801, 955, -861, -513, -748, -591, -627, -892}, - { 582, 522, 646, -594, -735, -659, -663, -533, -815}, - { 606, 625, 818, -739, -969, -999, -717, -763, -655}, - { 623, 591, 874, -720, -531, -1010, -758, -683, -746}, - { 669, 535, 1001, -700, -654, -523, -876, -559, -979}, - { 701, 938, 592, -642, -810, -542, -960, -860, -684}, - { 925, 820, 738, -741, -667, -592, -835, -657, -533}, - { 735, 790, 544, -567, -781, -840, -527, -610, -578}, - { 575, 788, 674, -886, -758, -519, -647, -607, -888}, - { 655, 783, 528, -1003, -677, -809, -840, -599, -545}, - { 527, 513, 677, -529, -699, -679, -544, -514, -897}, - { 782, 852, 940, -651, -718, -783, -597, -709, -863}, - { 578, 910, 513, -514, -581, -914, -654, -809, -515}, - { 692, 882, 734, -596, -993, -632, -937, -759, -526}, - { 586, 683, 715, -782, -818, -954, -670, -911, -999}, - { 739, 609, 717, -880, -518, -854, -534, -725, -1006}, - { 778, 773, 697, -588, -530, -527, -592, -584, -951}, - { 922, 785, 813, -707, -732, -624, -830, -602, -646}, - { 766, 651, 984, -974, -736, -626, -573, -827, -946}, - { 978, 596, 515, -569, -984, -600, -934, -694, -518}, - { 535, 757, 540, -792, -565, -799, -560, -559, -571}, - { 662, 687, 589, -890, -762, -791, -857, -924, -678}, - { 554, 536, 979, -580, -530, -512, -601, -561, -936}, - { 723, 982, 690, -694, -976, -662, -1022, -943, -932}, - { 936, 956, 527, -875, -965, -986, -856, -894, -543}, - { 590, 1002, 547, -577, -631, -536, -680, -980, -586}, - { 517, 653, 825, -660, -833, -526, -522, -834, -664}, - { 832, 592, 974, -964, -792, -564, -677, -686, -928}, - { 512, 957, 903, -957, -903, -844, -512, -894, -796}, - { 631, 545, 906, -672, -558, -965, -777, -581, -802}, - { 514, 720, 649, -723, -652, -913, -516, -1012, -824}, - { 596, 679, 694, -790, -807, -920, -693, -900, -940}, - { 617, 740, 979, -892, -590, -708, -743, -535, -936}, - { 711, 685, 877, -952, -609, -587, -987, -917, -752}, - { 655, 835, 848, -534, -542, -691, -838, -681, -702}, - { 754, 839, 698, -618, -515, -573, -556, -688, -954}, - { 871, 515, 769, -877, -655, -774, -742, -518, -578}, - { 955, 852, 573, -795, -535, -955, -892, -709, -643}, - { 640, 859, 587, -537, -735, -986, -801, -721, -674}, - { 792, 863, 554, -667, -858, -935, -612, -727, -601}, - { 843, 708, 682, -583, -562, -944, -694, -979, -910}, - { 971, 768, 552, -728, -524, -829, -921, -576, -596}, - { 891, 536, 690, -935, -601, -724, -776, -563, -931}, - {1016, 560, 663, -556, -659, -727, -1009, -614, -860}, - { 543, 870, 674, -924, -716, -573, -577, -739, -889}, - { 601, 999, 585, -586, -686, -571, -705, -975, -668}, - { 945, 966, 889, -892, -821, -840, -872, -912, -773}, - { 529, 912, 777, -943, -804, -692, -547, -812, -590}, - { 574, 1020, 714, -572, -801, -711, -643, -1016, -997}, - { 609, 922, 932, -549, -555, -840, -725, -831, -848}, - { 598, 778, 929, -909, -543, -707, -698, -592, -844}, - { 651, 772, 744, -982, -947, -561, -827, -582, -541}, - { 691, 957, 722, -646, -976, -675, -934, -894, -1020}, - { 729, 766, 984, -546, -701, -736, -520, -573, -945}, - { 547, 519, 632, -555, -675, -640, -585, -526, -780}, - { 583, 532, 922, -607, -525, -960, -664, -554, -831}, - { 633, 995, 603, -615, -745, -586, -783, -968, -710}, - { 677, 571, 874, -757, -578, -977, -896, -638, -747}, - { 602, 545, 666, -641, -783, -709, -708, -580, -866}, - { 627, 542, 875, -665, -536, -928, -769, -575, -748}, - { 672, 983, 598, -645, -786, -575, -882, -944, -700}, - { 692, 979, 730, -662, -988, -698, -937, -937, -521}, - { 668, 634, 872, -827, -569, -540, -871, -785, -742}, - { 711, 706, 674, -982, -937, -931, -988, -975, -889}, - { 739, 977, 595, -706, -860, -568, -534, -932, -691}, - { 759, 905, 763, -671, -566, -675, -563, -799, -569}, - { 756, 582, 763, -860, -563, -868, -558, -663, -568}, - { 748, 1013, 908, -741, -664, -898, -547, -1002, -805}, - { 804, 937, 950, -736, -746, -869, -631, -858, -882}, - { 785, 543, 998, -833, -766, -529, -602, -576, -973}, - { 999, 684, 942, -668, -920, -630, -975, -915, -868}, - { 626, 633, 996, -774, -609, -616, -765, -783, -970}, - { 626, 567, 835, -693, -1021, -925, -765, -628, -681}, - { 739, 571, 973, -825, -702, -543, -533, -637, -925}, - { 655, 769, 707, -984, -906, -531, -839, -577, -978}, - { 702, 952, 571, -653, -785, -532, -964, -886, -638}, - { 727, 712, 514, -1012, -730, -715, -516, -990, -516}, - { 744, 686, 741, -998, -539, -994, -541, -921, -536}, - { 731, 552, 714, -789, -1021, -772, -522, -596, -998}, - { 824, 991, 726, -798, -585, -703, -664, -959, -515}, - { 795, 615, 544, -955, -844, -653, -617, -738, -578}, - { 870, 575, 824, -978, -700, -926, -739, -646, -664}, - { 803, 832, 923, -653, -724, -750, -630, -677, -832}, - { 819, 839, 531, -671, -849, -871, -655, -688, -550}, - { 887, 786, 852, -681, -738, -654, -769, -603, -709}, - { 933, 764, 570, -696, -519, -851, -850, -570, -634}, - { 716, 906, 654, -634, -916, -579, -1003, -802, -837}, - { 784, 804, 563, -616, -864, -885, -601, -631, -620}, - { 774, 535, 876, -809, -662, -915, -585, -559, -749}, - { 807, 598, 649, -943, -1023, -758, -636, -699, -822}, - { 817, 759, 718, -606, -573, -533, -652, -563, -1008}, - { 831, 993, 846, -806, -687, -821, -675, -963, -699}, - { 858, 567, 605, -951, -1015, -670, -720, -628, -716}, - { 876, 1012, 651, -866, -557, -643, -750, -1001, -827}, - { 852, 548, 549, -913, -914, -588, -710, -587, -589}, - { 895, 1008, 871, -881, -761, -858, -782, -993, -741}, - { 892, 1000, 591, -872, -515, -578, -777, -977, -683}, - { 935, 516, 836, -944, -764, -844, -855, -521, -682}, - { 931, 612, 776, -557, -706, -929, -847, -733, -589}, - { 968, 614, 816, -581, -771, -980, -915, -738, -651}, - { 524, 777, 719, -796, -737, -546, -537, -590, -1012}, - { 549, 694, 786, -744, -843, -533, -589, -941, -603}, - { 882, 754, 534, -649, -920, -787, -759, -555, -557}, - { 597, 837, 766, -977, -895, -627, -697, -684, -574}, - { 635, 954, 704, -592, -873, -656, -788, -890, -969}, - { 803, 550, 798, -863, -626, -858, -630, -591, -622}, - { 699, 654, 798, -894, -545, -1021, -954, -837, -622}, - { 924, 767, 738, -693, -666, -553, -834, -575, -531}, - { 970, 675, 608, -639, -576, -801, -919, -890, -722}, - { 632, 706, 684, -873, -844, -944, -780, -976, -914}, - { 858, 767, 563, -643, -945, -844, -719, -574, -620}, - { 527, 765, 702, -788, -724, -525, -543, -572, -964}, - { 559, 924, 1003, -1009, -547, -905, -610, -833, -983}, - { 618, 524, 611, -633, -738, -625, -747, -536, -729}, - { 999, 942, 963, -920, -940, -886, -976, -867, -905}, - { 547, 857, 935, -916, -999, -783, -584, -718, -854}, - { 734, 926, 569, -665, -818, -515, -527, -838, -634}, - { 967, 746, 551, -705, -520, -804, -913, -544, -593}, - { 834, 633, 881, -515, -718, -545, -679, -783, -758}, - { 941, 701, 727, -645, -668, -997, -865, -961, -516}, - { 945, 564, 636, -521, -587, -701, -873, -623, -790}, - { 512, 563, 793, -563, -794, -873, -512, -619, -615}, - { 984, 556, 570, -534, -548, -620, -945, -604, -636}, - { 984, 540, 740, -519, -712, -782, -946, -570, -536}, - { 527, 764, 874, -787, -901, -652, -543, -570, -747}, - { 530, 664, 1014, -688, -525, -658, -549, -862, -1005}, - { 546, 515, 521, -550, -556, -525, -584, -519, -531}, - { 554, 934, 672, -1011, -728, -613, -600, -852, -882}, - { 598, 945, 556, -552, -650, -513, -700, -872, -603}, - { 627, 531, 733, -651, -899, -760, -769, -551, -525}, - { 576, 1020, 1014, -574, -571, -1011, -650, -1016, -1005}, - { 623, 924, 594, -563, -724, -537, -759, -835, -691}, - { 678, 909, 603, -602, -800, -536, -899, -807, -712}, - { 814, 744, 543, -592, -865, -790, -648, -541, -577} +static const int16_t gain_val_tab[256][3] = { + {541, 956, 768}, {877, 581, 568}, {675, 787, 635}, {624, 732, 668}, + {623, 839, 697}, {640, 693, 991}, {925, 687, 608}, {552, 797, 572}, + {535, 832, 799}, {762, 605, 577}, {832, 561, 1003}, {590, 687, 588}, + {646, 901, 732}, {828, 689, 896}, {875, 624, 848}, {571, 942, 1022}, + {824, 736, 643}, {517, 765, 512}, {562, 908, 761}, {694, 913, 675}, + {704, 524, 672}, {721, 757, 558}, {884, 551, 633}, {558, 1007, 846}, + {932, 746, 777}, {566, 822, 926}, {613, 771, 611}, {737, 671, 1008}, + {651, 594, 579}, {801, 636, 564}, {852, 910, 719}, {998, 614, 575}, + {665, 935, 628}, {631, 596, 829}, {644, 926, 526}, {879, 988, 613}, + {941, 692, 693}, {565, 672, 576}, {547, 628, 740}, {639, 532, 537}, + {955, 604, 598}, {562, 580, 900}, {603, 899, 621}, {746, 533, 624}, + {729, 514, 735}, {853, 551, 692}, {949, 1018, 1004}, {544, 988, 735}, + {789, 782, 821}, {897, 516, 754}, {517, 702, 828}, {586, 818, 763}, + {907, 652, 592}, {528, 652, 642}, {531, 708, 780}, {666, 625, 727}, + {947, 727, 554}, {549, 657, 981}, {605, 920, 852}, {624, 619, 983}, + {605, 909, 547}, {690, 935, 516}, {700, 612, 853}, {767, 832, 574}, + {523, 898, 923}, {722, 958, 691}, {613, 771, 928}, {758, 757, 584}, + {512, 567, 577}, {615, 638, 698}, {574, 642, 589}, {993, 682, 878}, + {539, 890, 913}, {694, 928, 544}, {805, 600, 680}, {540, 951, 782}, + {816, 950, 590}, {955, 847, 811}, {547, 883, 556}, {652, 888, 604}, + {863, 585, 855}, {1023, 997, 516}, {932, 614, 640}, {627, 564, 573}, + {876, 900, 724}, {515, 857, 896}, {647, 953, 879}, {806, 854, 857}, + {545, 583, 631}, {657, 601, 751}, {740, 905, 795}, {841, 1016, 568}, + {747, 589, 983}, {878, 613, 526}, {864, 723, 779}, {534, 674, 774}, + {950, 649, 939}, {590, 703, 899}, {618, 527, 579}, {725, 647, 972}, + {641, 647, 707}, {730, 663, 644}, {807, 572, 578}, {879, 611, 821}, + {667, 729, 841}, {782, 585, 751}, {802, 733, 976}, {850, 871, 708}, + {870, 743, 704}, {941, 899, 585}, {943, 632, 875}, {1023, 732, 638}, + {778, 753, 655}, {843, 945, 945}, {942, 969, 572}, {1008, 559, 854}, + {868, 729, 787}, {970, 686, 547}, {535, 635, 674}, {560, 636, 828}, + {994, 592, 833}, {548, 621, 694}, {550, 801, 955}, {582, 522, 646}, + {606, 625, 818}, {623, 591, 874}, {669, 535, 1001}, {701, 938, 592}, + {925, 820, 738}, {735, 790, 544}, {575, 788, 674}, {655, 783, 528}, + {527, 513, 677}, {782, 852, 940}, {578, 910, 513}, {692, 882, 734}, + {586, 683, 715}, {739, 609, 717}, {778, 773, 697}, {922, 785, 813}, + {766, 651, 984}, {978, 596, 515}, {535, 757, 540}, {662, 687, 589}, + {554, 536, 979}, {723, 982, 690}, {936, 956, 527}, {590, 1002, 547}, + {517, 653, 825}, {832, 592, 974}, {512, 957, 903}, {631, 545, 906}, + {514, 720, 649}, {596, 679, 694}, {617, 740, 979}, {711, 685, 877}, + {655, 835, 848}, {754, 839, 698}, {871, 515, 769}, {955, 852, 573}, + {640, 859, 587}, {792, 863, 554}, {843, 708, 682}, {971, 768, 552}, + {891, 536, 690}, {1016, 560, 663}, {543, 870, 674}, {601, 999, 585}, + {945, 966, 889}, {529, 912, 777}, {574, 1020, 714}, {609, 922, 932}, + {598, 778, 929}, {651, 772, 744}, {691, 957, 722}, {729, 766, 984}, + {547, 519, 632}, {583, 532, 922}, {633, 995, 603}, {677, 571, 874}, + {602, 545, 666}, {627, 542, 875}, {672, 983, 598}, {692, 979, 730}, + {668, 634, 872}, {711, 706, 674}, {739, 977, 595}, {759, 905, 763}, + {756, 582, 763}, {748, 1013, 908}, {804, 937, 950}, {785, 543, 998}, + {999, 684, 942}, {626, 633, 996}, {626, 567, 835}, {739, 571, 973}, + {655, 769, 707}, {702, 952, 571}, {727, 712, 514}, {744, 686, 741}, + {731, 552, 714}, {824, 991, 726}, {795, 615, 544}, {870, 575, 824}, + {803, 832, 923}, {819, 839, 531}, {887, 786, 852}, {933, 764, 570}, + {716, 906, 654}, {784, 804, 563}, {774, 535, 876}, {807, 598, 649}, + {817, 759, 718}, {831, 993, 846}, {858, 567, 605}, {876, 1012, 651}, + {852, 548, 549}, {895, 1008, 871}, {892, 1000, 591}, {935, 516, 836}, + {931, 612, 776}, {968, 614, 816}, {524, 777, 719}, {549, 694, 786}, + {882, 754, 534}, {597, 837, 766}, {635, 954, 704}, {803, 550, 798}, + {699, 654, 798}, {924, 767, 738}, {970, 675, 608}, {632, 706, 684}, + {858, 767, 563}, {527, 765, 702}, {559, 924, 1003}, {618, 524, 611}, + {999, 942, 963}, {547, 857, 935}, {734, 926, 569}, {967, 746, 551}, + {834, 633, 881}, {941, 701, 727}, {945, 564, 636}, {512, 563, 793}, + {984, 556, 570}, {984, 540, 740}, {527, 764, 874}, {530, 664, 1014}, + {546, 515, 521}, {554, 934, 672}, {598, 945, 556}, {627, 531, 733}, + {576, 1020, 1014}, {623, 924, 594}, {678, 909, 603}, {814, 744, 543} }; -static const uint8_t gain_exp_tab[256][9] = { - {14, 14, 14, 20, 20, 19, 21, 20, 20}, - {14, 14, 14, 20, 20, 20, 20, 21, 21}, - {14, 13, 14, 18, 20, 19, 21, 18, 21}, - {13, 13, 14, 18, 19, 19, 19, 18, 21}, - {13, 14, 13, 19, 18, 18, 19, 20, 19}, - {13, 14, 15, 19, 19, 20, 19, 21, 22}, - {13, 13, 13, 17, 17, 18, 18, 19, 19}, - {12, 14, 13, 18, 17, 19, 17, 20, 19}, - {13, 13, 13, 18, 18, 17, 19, 18, 18}, - {13, 13, 12, 18, 17, 17, 18, 19, 17}, - {13, 12, 13, 17, 17, 16, 18, 17, 18}, - {12, 13, 12, 17, 16, 17, 17, 19, 17}, - {12, 13, 13, 16, 17, 17, 17, 18, 18}, - {12, 13, 13, 16, 16, 17, 16, 19, 18}, - {12, 12, 13, 15, 16, 16, 16, 17, 18}, - {11, 13, 13, 15, 15, 17, 15, 18, 18}, - {13, 12, 13, 16, 17, 17, 18, 16, 19}, - {12, 12, 12, 16, 16, 16, 17, 16, 17}, - {13, 12, 12, 17, 17, 15, 19, 16, 16}, - {13, 12, 11, 16, 16, 14, 19, 16, 15}, - {12, 12, 12, 16, 16, 16, 17, 17, 17}, - {12, 13, 11, 16, 15, 16, 17, 18, 15}, - {12, 12, 11, 16, 14, 15, 16, 17, 15}, - {11, 13, 12, 15, 15, 16, 15, 18, 16}, - {12, 12, 12, 15, 15, 15, 16, 16, 16}, - {11, 12, 12, 15, 14, 15, 15, 16, 16}, - {11, 12, 12, 15, 15, 16, 15, 16, 17}, - {11, 12, 13, 15, 15, 16, 14, 17, 18}, - {11, 12, 11, 15, 14, 15, 15, 17, 15}, - {11, 12, 11, 15, 14, 15, 14, 17, 15}, - {11, 13, 12, 15, 14, 16, 14, 18, 17}, - {11, 12, 12, 14, 14, 16, 14, 17, 17}, - {12, 12, 12, 15, 16, 15, 17, 16, 17}, - {12, 11, 12, 15, 16, 15, 17, 15, 16}, - {12, 12, 11, 15, 15, 15, 17, 16, 15}, - {12, 12, 11, 15, 14, 14, 16, 16, 15}, - {13, 11, 11, 15, 15, 14, 18, 15, 15}, - {12, 11, 10, 15, 14, 13, 17, 15, 13}, - {11, 11, 11, 14, 14, 14, 15, 15, 14}, - {11, 11, 10, 14, 13, 13, 15, 15, 13}, - {12, 11, 12, 14, 15, 15, 16, 15, 17}, - {11, 11, 12, 14, 15, 15, 15, 15, 16}, - {11, 12, 11, 14, 14, 14, 15, 16, 15}, - {11, 11, 11, 14, 14, 14, 14, 15, 15}, - {11, 11, 12, 14, 14, 15, 14, 15, 16}, - {11, 11, 12, 14, 14, 15, 14, 15, 17}, - {11, 12, 12, 14, 14, 15, 14, 16, 16}, - {10, 12, 12, 13, 14, 15, 13, 16, 16}, - {11, 12, 11, 14, 13, 14, 14, 16, 14}, - {11, 11, 11, 14, 13, 14, 14, 15, 14}, - {10, 12, 11, 14, 13, 14, 13, 17, 14}, - {10, 12, 11, 14, 13, 14, 13, 16, 14}, - {11, 11, 11, 13, 13, 14, 14, 15, 15}, - {10, 11, 11, 13, 13, 14, 13, 15, 15}, - {10, 11, 12, 13, 14, 14, 13, 15, 16}, - {10, 11, 12, 13, 14, 15, 13, 15, 16}, - {11, 12, 11, 14, 13, 15, 14, 16, 15}, - {10, 12, 12, 14, 13, 15, 13, 17, 16}, - {10, 13, 12, 14, 14, 16, 13, 18, 16}, - {10, 12, 13, 14, 14, 16, 13, 17, 18}, - {10, 12, 11, 13, 13, 15, 13, 16, 15}, - {10, 12, 11, 13, 13, 15, 13, 16, 15}, - {10, 12, 12, 14, 13, 16, 13, 17, 16}, - {10, 12, 12, 13, 14, 16, 12, 16, 17}, - {12, 11, 12, 15, 16, 14, 17, 14, 16}, - {12, 11, 11, 14, 15, 13, 17, 14, 15}, - {11, 11, 12, 14, 14, 14, 15, 14, 16}, - {11, 11, 11, 13, 14, 14, 14, 14, 15}, - {11, 10, 11, 13, 14, 13, 15, 13, 15}, - {11, 10, 11, 13, 14, 13, 15, 13, 15}, - {12, 10, 10, 14, 14, 12, 17, 13, 13}, - {12, 10, 10, 13, 13, 11, 16, 13, 12}, - {11, 11, 11, 14, 14, 13, 15, 14, 14}, - {11, 11, 10, 13, 13, 13, 15, 14, 13}, - {11, 11, 10, 14, 12, 13, 14, 15, 13}, - {10, 12, 10, 14, 12, 13, 13, 16, 12}, - {11, 11, 11, 13, 14, 13, 14, 14, 15}, - {11, 11, 11, 13, 13, 13, 14, 14, 14}, - {10, 11, 11, 13, 13, 14, 13, 14, 15}, - {10, 11, 11, 12, 13, 13, 13, 14, 15}, - {11, 10, 11, 13, 13, 13, 14, 13, 14}, - {11, 11, 10, 13, 12, 13, 14, 14, 13}, - {11, 10, 10, 12, 12, 12, 14, 13, 13}, - {10, 10, 10, 12, 12, 12, 13, 13, 13}, - {11, 11, 10, 13, 12, 12, 14, 14, 12}, - {10, 11, 10, 13, 12, 12, 13, 14, 12}, - {10, 11, 10, 12, 11, 12, 13, 14, 12}, - {10, 11, 10, 12, 11, 12, 12, 14, 12}, - {10, 10, 11, 12, 13, 13, 13, 13, 15}, - {10, 10, 11, 12, 13, 13, 13, 13, 14}, - {10, 11, 11, 12, 12, 13, 12, 14, 14}, - {10, 11, 11, 12, 13, 13, 12, 14, 15}, - {10, 10, 11, 12, 12, 12, 12, 13, 14}, - {10, 10, 10, 11, 12, 12, 12, 13, 13}, - {10, 10, 11, 11, 12, 12, 12, 13, 14}, - { 9, 10, 11, 11, 12, 13, 11, 13, 14}, - {11, 11, 11, 13, 13, 13, 14, 15, 14}, - {10, 11, 11, 13, 12, 13, 13, 15, 14}, - {10, 11, 10, 13, 12, 13, 13, 15, 13}, - {10, 11, 11, 13, 12, 13, 12, 15, 14}, - {10, 11, 11, 13, 13, 14, 13, 15, 15}, - {10, 11, 11, 13, 13, 14, 12, 15, 15}, - {10, 11, 11, 13, 13, 14, 12, 15, 15}, - {10, 11, 12, 12, 13, 15, 12, 15, 16}, - {10, 12, 11, 14, 12, 14, 13, 16, 14}, - {10, 12, 11, 14, 12, 15, 12, 17, 14}, - {10, 12, 12, 13, 13, 15, 12, 16, 16}, - {10, 13, 12, 14, 13, 16, 12, 18, 17}, - {10, 12, 11, 13, 12, 15, 12, 16, 15}, - {10, 12, 11, 13, 12, 14, 12, 16, 15}, - {10, 12, 12, 13, 13, 15, 12, 17, 16}, - {10, 12, 12, 13, 13, 16, 12, 16, 17}, - {10, 12, 10, 13, 12, 14, 12, 16, 13}, - {10, 12, 11, 13, 12, 14, 12, 16, 14}, - {10, 12, 10, 13, 11, 13, 12, 16, 13}, - {10, 11, 11, 12, 12, 14, 12, 15, 14}, - {10, 11, 11, 12, 12, 13, 12, 14, 14}, - {10, 11, 11, 12, 12, 14, 12, 15, 15}, - { 9, 11, 11, 12, 12, 14, 11, 15, 15}, - { 9, 11, 12, 12, 13, 14, 11, 15, 16}, - {10, 12, 11, 13, 12, 15, 12, 17, 14}, - { 9, 12, 11, 13, 12, 15, 11, 17, 15}, - { 9, 12, 12, 13, 12, 15, 11, 16, 16}, - { 9, 12, 12, 13, 13, 16, 11, 17, 17}, - { 9, 12, 11, 13, 12, 15, 11, 17, 14}, - { 9, 12, 12, 13, 12, 16, 11, 17, 16}, - { 9, 12, 12, 13, 12, 15, 11, 17, 16}, - { 9, 13, 12, 13, 13, 16, 11, 18, 17}, - {12, 10, 11, 13, 14, 12, 16, 12, 14}, - {11, 10, 10, 12, 13, 12, 14, 12, 13}, - {10, 10, 11, 12, 13, 12, 13, 12, 15}, - {10, 10, 10, 12, 12, 12, 13, 12, 13}, - {11, 9, 10, 12, 13, 11, 15, 11, 13}, - {11, 10, 10, 12, 12, 11, 14, 12, 12}, - {10, 10, 9, 11, 11, 11, 13, 12, 11}, - {10, 10, 9, 11, 11, 10, 13, 12, 10}, - {10, 10, 10, 12, 12, 12, 13, 13, 13}, - {10, 10, 10, 12, 11, 12, 12, 13, 13}, - {10, 10, 10, 11, 11, 11, 12, 12, 13}, - {10, 10, 10, 11, 11, 11, 12, 12, 12}, - {10, 10, 10, 12, 11, 11, 12, 13, 12}, - {10, 10, 9, 11, 11, 11, 12, 13, 11}, - { 9, 10, 9, 11, 10, 11, 11, 12, 11}, - { 9, 10, 9, 11, 10, 11, 11, 13, 11}, - {10, 9, 11, 11, 12, 11, 13, 11, 14}, - {10, 10, 10, 11, 12, 11, 13, 12, 13}, - {10, 10, 10, 11, 12, 12, 12, 12, 13}, - { 9, 10, 10, 10, 11, 11, 11, 12, 13}, - {10, 9, 10, 11, 12, 10, 13, 11, 12}, - {10, 9, 10, 11, 11, 10, 12, 11, 12}, - { 9, 10, 10, 11, 11, 11, 11, 12, 12}, - { 9, 9, 10, 10, 10, 11, 11, 11, 12}, - { 9, 10, 10, 11, 11, 12, 11, 13, 13}, - { 9, 10, 10, 11, 11, 12, 11, 13, 13}, - { 9, 10, 11, 11, 11, 12, 11, 12, 14}, - { 9, 10, 11, 11, 11, 12, 11, 13, 14}, - { 9, 10, 10, 10, 10, 11, 11, 12, 12}, - { 9, 10, 10, 10, 10, 11, 10, 12, 13}, - { 9, 9, 10, 10, 10, 11, 10, 11, 12}, - { 9, 10, 10, 10, 10, 12, 10, 12, 13}, - {10, 11, 10, 12, 12, 13, 13, 14, 13}, - {10, 11, 10, 12, 12, 13, 12, 14, 13}, - {10, 11, 10, 12, 11, 13, 12, 15, 13}, - {10, 11, 10, 12, 11, 13, 12, 14, 13}, - {10, 10, 10, 12, 11, 12, 12, 13, 13}, - {10, 10, 10, 11, 11, 12, 12, 13, 13}, - { 9, 11, 10, 12, 11, 12, 11, 14, 13}, - { 9, 11, 10, 11, 11, 12, 11, 14, 13}, - {10, 11, 11, 12, 12, 13, 12, 14, 14}, - { 9, 11, 11, 12, 12, 13, 11, 14, 14}, - { 9, 11, 11, 11, 12, 13, 11, 14, 15}, - { 9, 11, 12, 11, 12, 14, 11, 14, 16}, - { 9, 11, 11, 12, 11, 13, 11, 14, 14}, - { 9, 11, 11, 12, 12, 13, 11, 14, 14}, - { 9, 11, 11, 11, 12, 13, 11, 14, 15}, - { 9, 11, 12, 11, 12, 14, 10, 14, 16}, - { 9, 11, 10, 12, 11, 13, 11, 15, 13}, - { 9, 11, 11, 12, 11, 14, 11, 15, 14}, - { 9, 12, 10, 12, 11, 13, 11, 16, 13}, - { 9, 11, 11, 12, 11, 14, 11, 15, 14}, - { 9, 11, 11, 12, 12, 14, 11, 15, 15}, - { 9, 11, 12, 12, 12, 15, 11, 15, 16}, - { 9, 12, 11, 12, 12, 14, 11, 16, 15}, - { 9, 12, 12, 12, 13, 15, 11, 16, 16}, - { 9, 12, 11, 13, 11, 14, 11, 17, 14}, - { 9, 12, 11, 13, 12, 15, 11, 17, 15}, - { 9, 12, 11, 12, 12, 14, 10, 16, 15}, - { 9, 12, 12, 12, 12, 15, 10, 16, 16}, - { 9, 12, 11, 13, 11, 15, 10, 17, 14}, - { 9, 13, 12, 13, 12, 16, 10, 18, 16}, - { 9, 13, 12, 13, 12, 16, 10, 18, 16}, - { 9, 12, 13, 13, 13, 16, 10, 17, 18}, - {10, 11, 10, 12, 11, 12, 12, 15, 12}, - { 9, 11, 10, 12, 10, 12, 11, 15, 12}, - { 9, 10, 10, 11, 11, 12, 11, 13, 12}, - { 9, 10, 10, 11, 10, 11, 10, 13, 12}, - { 9, 11, 10, 12, 11, 12, 11, 14, 13}, - { 9, 11, 10, 11, 11, 12, 11, 14, 13}, - { 9, 11, 10, 12, 11, 13, 10, 15, 13}, - { 9, 11, 11, 12, 11, 14, 10, 15, 14}, - { 9, 10, 10, 11, 11, 12, 10, 13, 13}, - { 9, 11, 10, 11, 10, 12, 10, 14, 12}, - { 9, 10, 10, 11, 11, 12, 10, 13, 13}, - { 9, 10, 11, 11, 11, 13, 10, 13, 14}, - { 9, 11, 11, 11, 11, 13, 10, 14, 14}, - { 9, 11, 11, 11, 12, 14, 10, 14, 15}, - { 9, 11, 11, 11, 11, 13, 10, 14, 14}, - { 9, 11, 11, 11, 11, 14, 10, 14, 15}, - { 9, 12, 10, 12, 11, 13, 11, 16, 13}, - { 9, 12, 10, 12, 11, 14, 10, 16, 13}, - { 9, 11, 11, 12, 11, 14, 10, 15, 14}, - { 9, 11, 11, 12, 12, 14, 10, 15, 15}, - { 9, 12, 11, 12, 11, 14, 10, 16, 15}, - { 9, 12, 12, 12, 12, 15, 10, 16, 16}, - { 9, 12, 11, 13, 12, 15, 10, 17, 15}, - { 9, 13, 12, 13, 12, 16, 10, 18, 17}, - { 9, 11, 10, 12, 11, 13, 10, 15, 13}, - { 9, 12, 11, 12, 11, 14, 10, 16, 14}, - { 9, 12, 11, 12, 11, 14, 10, 16, 15}, - { 9, 11, 12, 12, 12, 15, 10, 15, 16}, - { 9, 12, 11, 12, 11, 15, 10, 17, 14}, - { 9, 12, 12, 12, 12, 16, 10, 17, 16}, - { 8, 12, 11, 12, 11, 14, 9, 16, 15}, - { 8, 12, 12, 12, 12, 15, 9, 17, 16}, - {10, 9, 9, 10, 11, 10, 12, 10, 11}, - { 9, 9, 9, 10, 10, 9, 11, 10, 10}, - { 9, 10, 9, 10, 10, 10, 11, 12, 11}, - { 9, 9, 9, 10, 9, 10, 10, 11, 10}, - { 9, 9, 10, 10, 10, 11, 11, 11, 12}, - { 9, 9, 10, 9, 10, 10, 10, 10, 12}, - { 9, 9, 9, 9, 9, 10, 10, 11, 11}, - { 8, 9, 9, 9, 9, 10, 9, 11, 11}, - { 9, 10, 9, 10, 10, 11, 10, 12, 11}, - { 8, 10, 9, 10, 9, 10, 9, 12, 11}, - { 8, 10, 10, 10, 9, 11, 9, 12, 12}, - { 8, 9, 10, 9, 10, 11, 9, 11, 13}, - { 9, 9, 9, 9, 9, 9, 10, 10, 10}, - { 7, 8, 8, 7, 7, 7, 7, 8, 8}, - { 8, 10, 9, 9, 9, 10, 8, 12, 11}, - { 8, 9, 9, 8, 8, 10, 8, 10, 11}, - { 9, 11, 10, 11, 10, 12, 10, 15, 12}, - { 9, 11, 10, 11, 10, 13, 10, 15, 12}, - { 9, 10, 10, 10, 10, 12, 10, 13, 13}, - { 8, 10, 11, 10, 11, 13, 9, 13, 14}, - { 9, 11, 10, 11, 10, 13, 10, 15, 13}, - { 9, 11, 11, 11, 11, 14, 10, 15, 14}, - { 8, 11, 11, 11, 11, 13, 9, 14, 14}, - { 8, 11, 12, 11, 11, 14, 9, 15, 16}, - { 8, 10, 9, 10, 9, 11, 9, 13, 11}, - { 8, 11, 10, 11, 10, 12, 9, 14, 13}, - { 8, 11, 10, 10, 10, 12, 9, 14, 13}, - { 8, 10, 11, 10, 11, 13, 9, 13, 14}, - { 8, 12, 11, 11, 10, 14, 9, 16, 14}, - { 8, 12, 11, 11, 11, 14, 9, 16, 15}, - { 8, 11, 10, 10, 10, 12, 9, 14, 13}, - { 8, 11, 10, 10, 10, 13, 8, 14, 13} +static const uint8_t gain_exp_tab[256][3] = { + {14, 14, 14}, {14, 14, 14}, {14, 13, 14}, {13, 13, 14}, + {13, 14, 13}, {13, 14, 15}, {13, 13, 13}, {12, 14, 13}, + {13, 13, 13}, {13, 13, 12}, {13, 12, 13}, {12, 13, 12}, + {12, 13, 13}, {12, 13, 13}, {12, 12, 13}, {11, 13, 13}, + {13, 12, 13}, {12, 12, 12}, {13, 12, 12}, {13, 12, 11}, + {12, 12, 12}, {12, 13, 11}, {12, 12, 11}, {11, 13, 12}, + {12, 12, 12}, {11, 12, 12}, {11, 12, 12}, {11, 12, 13}, + {11, 12, 11}, {11, 12, 11}, {11, 13, 12}, {11, 12, 12}, + {12, 12, 12}, {12, 11, 12}, {12, 12, 11}, {12, 12, 11}, + {13, 11, 11}, {12, 11, 10}, {11, 11, 11}, {11, 11, 10}, + {12, 11, 12}, {11, 11, 12}, {11, 12, 11}, {11, 11, 11}, + {11, 11, 12}, {11, 11, 12}, {11, 12, 12}, {10, 12, 12}, + {11, 12, 11}, {11, 11, 11}, {10, 12, 11}, {10, 12, 11}, + {11, 11, 11}, {10, 11, 11}, {10, 11, 12}, {10, 11, 12}, + {11, 12, 11}, {10, 12, 12}, {10, 13, 12}, {10, 12, 13}, + {10, 12, 11}, {10, 12, 11}, {10, 12, 12}, {10, 12, 12}, + {12, 11, 12}, {12, 11, 11}, {11, 11, 12}, {11, 11, 11}, + {11, 10, 11}, {11, 10, 11}, {12, 10, 10}, {12, 10, 10}, + {11, 11, 11}, {11, 11, 10}, {11, 11, 10}, {10, 12, 10}, + {11, 11, 11}, {11, 11, 11}, {10, 11, 11}, {10, 11, 11}, + {11, 10, 11}, {11, 11, 10}, {11, 10, 10}, {10, 10, 10}, + {11, 11, 10}, {10, 11, 10}, {10, 11, 10}, {10, 11, 10}, + {10, 10, 11}, {10, 10, 11}, {10, 11, 11}, {10, 11, 11}, + {10, 10, 11}, {10, 10, 10}, {10, 10, 11}, { 9, 10, 11}, + {11, 11, 11}, {10, 11, 11}, {10, 11, 10}, {10, 11, 11}, + {10, 11, 11}, {10, 11, 11}, {10, 11, 11}, {10, 11, 12}, + {10, 12, 11}, {10, 12, 11}, {10, 12, 12}, {10, 13, 12}, + {10, 12, 11}, {10, 12, 11}, {10, 12, 12}, {10, 12, 12}, + {10, 12, 10}, {10, 12, 11}, {10, 12, 10}, {10, 11, 11}, + {10, 11, 11}, {10, 11, 11}, { 9, 11, 11}, { 9, 11, 12}, + {10, 12, 11}, { 9, 12, 11}, { 9, 12, 12}, { 9, 12, 12}, + { 9, 12, 11}, { 9, 12, 12}, { 9, 12, 12}, { 9, 13, 12}, + {12, 10, 11}, {11, 10, 10}, {10, 10, 11}, {10, 10, 10}, + {11, 9, 10}, {11, 10, 10}, {10, 10, 9}, {10, 10, 9}, + {10, 10, 10}, {10, 10, 10}, {10, 10, 10}, {10, 10, 10}, + {10, 10, 10}, {10, 10, 9}, { 9, 10, 9}, { 9, 10, 9}, + {10, 9, 11}, {10, 10, 10}, {10, 10, 10}, { 9, 10, 10}, + {10, 9, 10}, {10, 9, 10}, { 9, 10, 10}, { 9, 9, 10}, + { 9, 10, 10}, { 9, 10, 10}, { 9, 10, 11}, { 9, 10, 11}, + { 9, 10, 10}, { 9, 10, 10}, { 9, 9, 10}, { 9, 10, 10}, + {10, 11, 10}, {10, 11, 10}, {10, 11, 10}, {10, 11, 10}, + {10, 10, 10}, {10, 10, 10}, { 9, 11, 10}, { 9, 11, 10}, + {10, 11, 11}, { 9, 11, 11}, { 9, 11, 11}, { 9, 11, 12}, + { 9, 11, 11}, { 9, 11, 11}, { 9, 11, 11}, { 9, 11, 12}, + { 9, 11, 10}, { 9, 11, 11}, { 9, 12, 10}, { 9, 11, 11}, + { 9, 11, 11}, { 9, 11, 12}, { 9, 12, 11}, { 9, 12, 12}, + { 9, 12, 11}, { 9, 12, 11}, { 9, 12, 11}, { 9, 12, 12}, + { 9, 12, 11}, { 9, 13, 12}, { 9, 13, 12}, { 9, 12, 13}, + {10, 11, 10}, { 9, 11, 10}, { 9, 10, 10}, { 9, 10, 10}, + { 9, 11, 10}, { 9, 11, 10}, { 9, 11, 10}, { 9, 11, 11}, + { 9, 10, 10}, { 9, 11, 10}, { 9, 10, 10}, { 9, 10, 11}, + { 9, 11, 11}, { 9, 11, 11}, { 9, 11, 11}, { 9, 11, 11}, + { 9, 12, 10}, { 9, 12, 10}, { 9, 11, 11}, { 9, 11, 11}, + { 9, 12, 11}, { 9, 12, 12}, { 9, 12, 11}, { 9, 13, 12}, + { 9, 11, 10}, { 9, 12, 11}, { 9, 12, 11}, { 9, 11, 12}, + { 9, 12, 11}, { 9, 12, 12}, { 8, 12, 11}, { 8, 12, 12}, + {10, 9, 9}, { 9, 9, 9}, { 9, 10, 9}, { 9, 9, 9}, + { 9, 9, 10}, { 9, 9, 10}, { 9, 9, 9}, { 8, 9, 9}, + { 9, 10, 9}, { 8, 10, 9}, { 8, 10, 10}, { 8, 9, 10}, + { 9, 9, 9}, { 7, 8, 8}, { 8, 10, 9}, { 8, 9, 9}, + { 9, 11, 10}, { 9, 11, 10}, { 9, 10, 10}, { 8, 10, 11}, + { 9, 11, 10}, { 9, 11, 11}, { 8, 11, 11}, { 8, 11, 12}, + { 8, 10, 9}, { 8, 11, 10}, { 8, 11, 10}, { 8, 10, 11}, + { 8, 12, 11}, { 8, 12, 11}, { 8, 11, 10}, { 8, 11, 10} }; static const int8_t cb1_vects[128][40]={ @@ -1831,135 +1447,107 @@ static const int8_t cb2_vects[128][40]={ } }; -static const uint32_t cb1_base[128]={ - 314527, 295599, 293848, 280320, 336779, 291703, 297354, 266749, - 325815, 305109, 310555, 294891, 349515, 300052, 313812, 278588, - 326231, 348357, 322076, 347246, 335655, 327567, 314037, 310198, - 343640, 370152, 349471, 382719, 353433, 344311, 338152, 333632, - 314810, 285147, 304708, 279643, 319779, 271292, 295149, 257376, - 338219, 302387, 335244, 302877, 343236, 285341, 321676, 274547, - 316321, 320899, 325378, 333870, 309279, 291473, 302532, 288065, - 344907, 351169, 369278, 382224, 334752, 312711, 335747, 316511, - 316511, 335747, 312711, 334752, 382224, 369278, 351169, 344907, - 288065, 302532, 291473, 309279, 333870, 325378, 320899, 316321, - 274547, 321676, 285341, 343236, 302877, 335244, 302387, 338219, - 257376, 295149, 271292, 319779, 279643, 304708, 285147, 314810, - 333632, 338152, 344311, 353433, 382719, 349471, 370152, 343640, - 310198, 314037, 327567, 335655, 347246, 322076, 348357, 326231, - 278588, 313812, 300052, 349515, 294891, 310555, 305109, 325815, - 266749, 297354, 291703, 336779, 280320, 293848, 295599, 314527 +static const uint16_t cb1_base[128]={ + 19657, 18474, 18365, 17520, 21048, 18231, 18584, 16671, + 20363, 19069, 19409, 18430, 21844, 18753, 19613, 17411, + 20389, 21772, 20129, 21702, 20978, 20472, 19627, 19387, + 21477, 23134, 21841, 23919, 22089, 21519, 21134, 20852, + 19675, 17821, 19044, 17477, 19986, 16955, 18446, 16086, + 21138, 18899, 20952, 18929, 21452, 17833, 20104, 17159, + 19770, 20056, 20336, 20866, 19329, 18217, 18908, 18004, + 21556, 21948, 23079, 23889, 20922, 19544, 20984, 19781, + 19781, 20984, 19544, 20922, 23889, 23079, 21948, 21556, + 18004, 18908, 18217, 19329, 20866, 20336, 20056, 19770, + 17159, 20104, 17833, 21452, 18929, 20952, 18899, 21138, + 16086, 18446, 16955, 19986, 17477, 19044, 17821, 19675, + 20852, 21134, 21519, 22089, 23919, 21841, 23134, 21477, + 19387, 19627, 20472, 20978, 21702, 20129, 21772, 20389, + 17411, 19613, 18753, 21844, 18430, 19409, 19069, 20363, + 16671, 18584, 18231, 21048, 17520, 18365, 18474, 19657, }; -static const uint32_t cb2_base[128]={ - 194793, 214093, 222075, 221325, 210734, 211641, 211270, 192855, - 198561, 223821, 229577, 234105, 209600, 214643, 211594, 196292, - 191722, 221201, 215984, 227369, 222035, 236618, 220978, 209746, - 183193, 212405, 205343, 219484, 203652, 219140, 204153, 198495, - 163695, 194973, 186057, 210587, 188197, 215336, 197004, 205097, - 167090, 204380, 192189, 224334, 189091, 221215, 199256, 211624, - 167150, 210594, 190109, 228813, 205750, 260616, 215853, 240851, - 162492, 205131, 184310, 223583, 192669, 241298, 202170, 227169, - 227169, 202170, 241298, 192669, 223583, 184310, 205131, 162492, - 240851, 215853, 260616, 205750, 228813, 190109, 210594, 167150, - 211624, 199256, 221215, 189091, 224334, 192189, 204380, 167090, - 205097, 197004, 215336, 188197, 210587, 186057, 194973, 163695, - 198495, 204153, 219140, 203652, 219484, 205343, 212405, 183193, - 209746, 220978, 236618, 222035, 227369, 215984, 221201, 191722, - 196292, 211594, 214643, 209600, 234105, 229577, 223821, 198561, - 192855, 211270, 211641, 210734, 221325, 222075, 214093, 194793 +static const uint16_t cb2_base[128]={ + 12174, 13380, 13879, 13832, 13170, 13227, 13204, 12053, + 12410, 13988, 14348, 14631, 13100, 13415, 13224, 12268, + 11982, 13825, 13499, 14210, 13877, 14788, 13811, 13109, + 11449, 13275, 12833, 13717, 12728, 13696, 12759, 12405, + 10230, 12185, 11628, 13161, 11762, 13458, 12312, 12818, + 10443, 12773, 12011, 14020, 11818, 13825, 12453, 13226, + 10446, 13162, 11881, 14300, 12859, 16288, 13490, 15053, + 10155, 12820, 11519, 13973, 12041, 15081, 12635, 14198, + 14198, 12635, 15081, 12041, 13973, 11519, 12820, 10155, + 15053, 13490, 16288, 12859, 14300, 11881, 13162, 10446, + 13226, 12453, 13825, 11818, 14020, 12011, 12773, 10443, + 12818, 12312, 13458, 11762, 13161, 11628, 12185, 10230, + 12405, 12759, 13696, 12728, 13717, 12833, 13275, 11449, + 13109, 13811, 14788, 13877, 14210, 13499, 13825, 11982, + 12268, 13224, 13415, 13100, 14631, 14348, 13988, 12410, + 12053, 13204, 13227, 13170, 13832, 13879, 13380, 12174, }; -static const int16_t energy_tab[63]={ - 0, 6, 16, 18, 20, 23, 25, 29, - 32, 36, 41, 46, 51, 57, 65, 73, - 81, 91, 103, 115, 129, 145, 163, 183, - 205, 230, 259, 290, 326, 365, 410, 460, - 516, 579, 650, 730, 819, 919, 1031, 1157, - 1298, 1456, 1634, 1833, 2057, 2308, 2590, 2906, - 3261, 3659, 4105, 4606, 5168, 5799, 6507, 7301, - 8192, 9191, 10313, 11571, 12983, 14567, 16345 +static const int16_t energy_tab[32]={ + 0, 16, 20, 25, 32, 41, 51, 65, + 81, 103, 129, 163, 205, 259, 326, 410, + 516, 650, 819, 1031, 1298, 1634, 2057, 2590, + 3261, 4105, 5168, 6507, 8192, 10313, 12983, 16345 }; -static const int16_t lpc_refl_cb1[127]={ - -4041, -4029, -4018, -4008, -3998, -3988, -3977, -3966, - -3954, -3942, -3930, -3918, -3906, -3892, -3879, -3866, - -3852, -3839, -3825, -3810, -3795, -3779, -3764, -3748, - -3731, -3715, -3699, -3683, -3666, -3649, -3631, -3613, - -3594, -3574, -3555, -3534, -3513, -3491, -3468, -3444, - -3420, -3396, -3372, -3346, -3321, -3295, -3268, -3240, - -3212, -3183, -3153, -3122, -3090, -3056, -3021, -2983, - -2944, -2903, -2863, -2817, -2772, -2724, -2676, -2620, - -2565, -2505, -2445, -2387, -2328, -2265, -2202, -2137, - -2072, -2006, -1941, -1874, -1808, -1734, -1660, -1584, - -1508, -1428, -1348, -1267, -1185, -1090, -994, -896, - -798, -699, -600, -487, -374, -242, -110, 21, - 152, 300, 447, 584, 720, 851, 982, 1105, - 1229, 1342, 1456, 1569, 1682, 1799, 1916, 2023, - 2130, 2242, 2353, 2474, 2595, 2724, 2853, 2986, - 3118, 3240, 3363, 3475, 3588, 3701, 3814 +static const int16_t lpc_refl_cb1[64]={ + -4041, -4018, -3998, -3977, -3954, -3930, -3906, -3879, + -3852, -3825, -3795, -3764, -3731, -3699, -3666, -3631, + -3594, -3555, -3513, -3468, -3420, -3372, -3321, -3268, + -3212, -3153, -3090, -3021, -2944, -2863, -2772, -2676, + -2565, -2445, -2328, -2202, -2072, -1941, -1808, -1660, + -1508, -1348, -1185, -994, -798, -600, -374, -110, + 152, 447, 720, 982, 1229, 1456, 1682, 1916, + 2130, 2353, 2595, 2853, 3118, 3363, 3588, 3814 }; -static const int16_t lpc_refl_cb2[63]={ - -3091, -2739, -2386, -2129, -1871, -1648, -1425, -1223, - -1021, -835, -649, -483, -316, -168, -20, 123, - 267, 406, 544, 677, 810, 937, 1065, 1185, - 1305, 1420, 1534, 1645, 1756, 1863, 1970, 2071, - 2171, 2265, 2359, 2448, 2536, 2618, 2700, 2777, - 2854, 2925, 2996, 3064, 3133, 3198, 3263, 3324, - 3386, 3442, 3499, 3551, 3603, 3652, 3701, 3745, - 3789, 3829, 3870, 3908, 3947, 3983, 4020 +static const int16_t lpc_refl_cb2[32]={ + -3091, -2386, -1871, -1425, -1021, -649, -316, -20, + 267, 544, 810, 1065, 1305, 1534, 1756, 1970, + 2171, 2359, 2536, 2700, 2854, 2996, 3133, 3263, + 3386, 3499, 3603, 3701, 3789, 3870, 3947, 4020 }; -static const int16_t lpc_refl_cb3[63]={ - -3525, -3410, -3295, -3188, -3081, -2985, -2890, -2793, - -2696, -2603, -2511, -2419, -2328, -2238, -2149, -2064, - -1979, -1898, -1817, -1737, -1658, -1578, -1498, -1420, - -1341, -1265, -1188, -1110, -1032, -954, -876, -798, - -721, -641, -561, -478, -394, -311, -228, -141, - -54, 32, 119, 208, 296, 390, 484, 584, - 683, 789, 895, 1009, 1123, 1248, 1373, 1512, - 1651, 1808, 1965, 2162, 2360, 2607, 2854 +static const int16_t lpc_refl_cb3[32]={ + -3525, -3295, -3081, -2890, -2696, -2511, -2328, -2149, + -1979, -1817, -1658, -1498, -1341, -1188, -1032, -876, + -721, -561, -394, -228, -54, 119, 296, 484, + 683, 895, 1123, 1373, 1651, 1965, 2360, 2854 }; -static const int16_t lpc_refl_cb4[31]={ - -1845, -1451, -1057, -790, -522, -300, -77, 111, - 301, 474, 647, 811, 975, 1130, 1285, 1434, - 1582, 1727, 1873, 2018, 2163, 2308, 2452, 2594, - 2735, 2876, 3017, 3158, 3299, 3434, 3569 +static const int16_t lpc_refl_cb4[16]={ + -1845, -1057, -522, -77, 301, 647, 975, 1285, + 1582, 1873, 2163, 2452, 2735, 3017, 3299, 3569 }; -static const int16_t lpc_refl_cb5[31]={ - -2691, -2439, -2187, -1987, -1788, -1611, -1435, -1276, - -1118, -977, -837, -704, -571, -444, -316, -188, - -59, 71, 201, 336, 470, 614, 759, 918, - 1077, 1267, 1457, 1682, 1908, 2201, 2495 +static const int16_t lpc_refl_cb5[16]={ + -2691, -2187, -1788, -1435, -1118, -837, -571, -316, + -59, 201, 470, 759, 1077, 1457, 1908, 2495 }; -static const int16_t lpc_refl_cb6[15]={ - -1372, -923, -474, -170, 133, 383, 632, 866, - 1100, 1335, 1571, 1823, 2075, 2374, 2672 +static const int16_t lpc_refl_cb6[8]={ + -1372, -474, 133, 632, 1100, 1571, 2075, 2672 }; -static const int16_t lpc_refl_cb7[15]={ - -2389, -2088, -1787, -1509, -1231, -974, -717, -478, - -239, -2, 234, 502, 770, 1122, 1474 +static const int16_t lpc_refl_cb7[8]={ + -2389, -1787, -1231, -717, -239, 234, 770, 1474 }; -static const int16_t lpc_refl_cb8[15]={ - -1569, -1217, -864, -580, -296, -47, 200, 435, - 670, 911, 1151, 1430, 1709, 2047, 2385 +static const int16_t lpc_refl_cb8[8]={ + -1569, -864, -296, 200, 670, 1151, 1709, 2385 }; -static const int16_t lpc_refl_cb9[15]={ - -2200, -1904, -1608, -1335, -1062, -816, -569, -344, - -120, 108, 338, 600, 863, 1242, 1621 +static const int16_t lpc_refl_cb9[8]={ + -2200, -1608, -1062, -569, -120, 338, 863, 1621 }; -static const int16_t lpc_refl_cb10[7]={ - -617, -213, 190, 496, 802, 1142, 1483 +static const int16_t lpc_refl_cb10[4]={ + -617, 190, 802, 1483 }; -static const int16_t *lpc_refl_cb[10]={ +static const int16_t * const lpc_refl_cb[10]={ lpc_refl_cb1, lpc_refl_cb2, lpc_refl_cb3, lpc_refl_cb4, lpc_refl_cb5, lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10 }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra288.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra288.c @@ -20,228 +20,206 @@ */ #include "avcodec.h" +#define ALT_BITSTREAM_READER_LE +#include "bitstream.h" #include "ra288.h" typedef struct { - float history[8]; - float output[40]; - float pr1[36]; - float pr2[10]; - int phase, phasep; - - float st1a[111],st1b[37],st1[37]; - float st2a[38],st2b[11],st2[11]; - float sb[41]; - float lhist[10]; + float history[8]; + float output[40]; + float pr1[36]; + float pr2[10]; + int phase; + + float st1a[111], st1b[37], st1[37]; + float st2a[38], st2b[11], st2[11]; + float sb[41]; + float lhist[10]; } Real288_internal; -static int ra288_decode_init(AVCodecContext * avctx) +static inline float scalar_product_float(const float * v1, const float * v2, + int size) { - Real288_internal *glob=avctx->priv_data; - memset(glob,0,sizeof(Real288_internal)); - return 0; -} + float res = 0.; -static void prodsum(float *tgt, float *src, int len, int n); -static void co(int n, int i, int j, float *in, float *out, float *st1, float *st2, const float *table); -static int pred(float *in, float *tgt, int n); -static void colmult(float *tgt, float *m1, const float *m2, int n); + while (size--) + res += *v1++ * *v2++; - -/* initial decode */ -static void unpack(unsigned short *tgt, const unsigned char *src, unsigned int len) -{ - int x,y,z; - int n,temp; - int buffer[len]; - - for (x=0;x<len;tgt[x++]=0) - buffer[x]=9+(x&1); - - for (x=y=z=0;x<len/*was 38*/;x++) { - n=buffer[y]-z; - temp=src[x]; - if (n<8) temp&=255>>(8-n); - tgt[y]+=temp<<z; - if (n<=8) { - tgt[++y]+=src[x]>>n; - z=8-n; - } else z+=8; - } -} - -static void update(Real288_internal *glob) -{ - int x,y; - float buffer1[40],temp1[37]; - float buffer2[8],temp2[11]; - - for (x=0,y=glob->phasep+5;x<40;buffer1[x++]=glob->output[(y++)%40]); - co(36,40,35,buffer1,temp1,glob->st1a,glob->st1b,table1); - if (pred(temp1,glob->st1,36)) - colmult(glob->pr1,glob->st1,table1a,36); - - for (x=0,y=glob->phase+1;x<8;buffer2[x++]=glob->history[(y++)%8]); - co(10,8,20,buffer2,temp2,glob->st2a,glob->st2b,table2); - if (pred(temp2,glob->st2,10)) - colmult(glob->pr2,glob->st2,table2a,10); + return res; } /* Decode and produce output */ -static void decode(Real288_internal *glob, unsigned int input) +static void decode(Real288_internal *glob, float gain, int cb_coef) { - unsigned int x,y; - float f; - double sum,sumsum; - float *p1,*p2; - float buffer[5]; - const float *table; - - for (x=36;x--;glob->sb[x+5]=glob->sb[x]); - for (x=5;x--;) { - p1=glob->sb+x;p2=glob->pr1; - for (sum=0,y=36;y--;sum-=(*(++p1))*(*(p2++))); - glob->sb[x]=sum; - } - - f=amptable[input&7]; - table=codetable+(input>>3)*5; - - /* convert log and do rms */ - for (sum=32,x=10;x--;sum-=glob->pr2[x]*glob->lhist[x]); - if (sum<0) sum=0; else if (sum>60) sum=60; - - sumsum=exp(sum*0.1151292546497)*f; /* pow(10.0,sum/20)*f */ - for (sum=0,x=5;x--;) { buffer[x]=table[x]*sumsum; sum+=buffer[x]*buffer[x]; } - if ((sum/=5)<1) sum=1; - - /* shift and store */ - for (x=10;--x;glob->lhist[x]=glob->lhist[x-1]); - *glob->lhist=glob->history[glob->phase]=10*log10(sum)-32; - - for (x=1;x<5;x++) for (y=x;y--;buffer[x]-=glob->pr1[x-y-1]*buffer[y]); - - /* output */ - for (x=0;x<5;x++) { - f=glob->sb[4-x]+buffer[x]; - if (f>4095) f=4095; else if (f<-4095) f=-4095; - glob->output[glob->phasep+x]=glob->sb[4-x]=f; - } + int x, y; + double sumsum; + float sum, buffer[5]; + + memmove(glob->sb + 5, glob->sb, 36 * sizeof(*glob->sb)); + + for (x=4; x >= 0; x--) + glob->sb[x] = -scalar_product_float(glob->sb + x + 1, glob->pr1, 36); + + /* convert log and do rms */ + sum = 32. - scalar_product_float(glob->pr2, glob->lhist, 10); + + sum = av_clipf(sum, 0, 60); + + sumsum = exp(sum * 0.1151292546497) * gain; /* pow(10.0,sum/20)*f */ + + for (x=0; x < 5; x++) + buffer[x] = codetable[cb_coef][x] * sumsum; + + sum = scalar_product_float(buffer, buffer, 5) / 5; + + sum = FFMAX(sum, 1); + + /* shift and store */ + memmove(glob->lhist, glob->lhist - 1, 10 * sizeof(*glob->lhist)); + + *glob->lhist = glob->history[glob->phase] = 10 * log10(sum) - 32; + + for (x=1; x < 5; x++) + for (y=x-1; y >= 0; y--) + buffer[x] -= glob->pr1[x-y-1] * buffer[y]; + + /* output */ + for (x=0; x < 5; x++) { + glob->output[glob->phase*5+x] = glob->sb[4-x] = + av_clipf(glob->sb[4-x] + buffer[x], -4095, 4095); + } } /* column multiply */ -static void colmult(float *tgt, float *m1, const float *m2, int n) +static void colmult(float *tgt, const float *m1, const float *m2, int n) { - while (n--) - *(tgt++)=(*(m1++))*(*(m2++)); + while (n--) + *(tgt++) = (*(m1++)) * (*(m2++)); } -static int pred(float *in, float *tgt, int n) +static int pred(const float *in, float *tgt, int n) { - int x,y; - float *p1,*p2; - double f0,f1,f2; - float temp; - - if (in[n]==0) return 0; - if ((f0=*in)<=0) return 0; - - for (x=1;;x++) { - if (n<x) return 1; - - p1=in+x; - p2=tgt; - f1=*(p1--); - for (y=x;--y;f1+=(*(p1--))*(*(p2++))); - - p1=tgt+x-1; - p2=tgt; - *(p1--)=f2=-f1/f0; - for (y=x>>1;y--;) { - temp=*p2+*p1*f2; - *(p1--)+=*p2*f2; - *(p2++)=temp; + int x, y; + double f0, f1, f2; + + if (in[n] == 0) + return 0; + + if ((f0 = *in) <= 0) + return 0; + + in--; // To avoid a -1 subtraction in the inner loop + + for (x=1; x <= n; x++) { + f1 = in[x+1]; + + for (y=0; y < x - 1; y++) + f1 += in[x-y]*tgt[y]; + + tgt[x-1] = f2 = -f1/f0; + for (y=0; y < x >> 1; y++) { + float temp = tgt[y] + tgt[x-y-2]*f2; + tgt[x-y-2] += tgt[y]*f2; + tgt[y] = temp; + } + if ((f0 += f1*f2) < 0) + return 0; } - if ((f0+=f1*f2)<0) return 0; - } + + return 1; } -static void co(int n, int i, int j, float *in, float *out, float *st1, float *st2, const float *table) +/* product sum (lsf) */ +static void prodsum(float *tgt, const float *src, int len, int n) { - int a,b,c; - unsigned int x; - float *fp; - float buffer1[37]; - float buffer2[37]; - float work[111]; - - /* rotate and multiply */ - c=(b=(a=n+i)+j)-i; - fp=st1+i; - for (x=0;x<b;x++) { - if (x==c) fp=in; - work[x]=*(table++)*(*(st1++)=*(fp++)); - } - - prodsum(buffer1,work+n,i,n); - prodsum(buffer2,work+a,j,n); - - for (x=0;x<=n;x++) { - *st2=*st2*(0.5625)+buffer1[x]; - out[x]=*(st2++)+buffer2[x]; - } - *out*=1.00390625; /* to prevent clipping */ + for (; n >= 0; n--) + tgt[n] = scalar_product_float(src, src - n, len); + } -/* product sum (lsf) */ -static void prodsum(float *tgt, float *src, int len, int n) +static void co(int n, int i, int j, const float *in, float *out, float *st1, + float *st2, const float *table) { - unsigned int x; - float *p1,*p2; - double sum; - - while (n>=0) - { - p1=(p2=src)-n; - for (sum=0,x=len;x--;sum+=(*p1++)*(*p2++)); - tgt[n--]=sum; - } + unsigned int x; + const float *fp; + float buffer1[37]; + float buffer2[37]; + float work[111]; + + /* rotate and multiply */ + fp = st1 + i; + for (x=0; x < n + i + j; x++) { + if (x == n + j) + fp=in; + st1[x] = *(fp++); + work[x] = table[x] * st1[x]; + } + + prodsum(buffer1, work + n , i, n); + prodsum(buffer2, work + n + i, j, n); + + for (x=0; x <= n; x++) { + st2[x] = st2[x] * 0.5625 + buffer1[x]; + out[x] = st2[x] + buffer2[x]; + } + *out *= 1.00390625; /* to prevent clipping */ } -static void * decode_block(AVCodecContext * avctx, const unsigned char *in, signed short int *out,unsigned len) +static void update(Real288_internal *glob) { - int x,y; - Real288_internal *glob=avctx->priv_data; - unsigned short int buffer[len]; - - unpack(buffer,in,len); - for (x=0;x<32;x++) - { - glob->phasep=(glob->phase=x&7)*5; - decode(glob,buffer[x]); - for (y=0;y<5;*(out++)=8*glob->output[glob->phasep+(y++)]); - if (glob->phase==3) update(glob); - } - return out; + float buffer1[40], temp1[37]; + float buffer2[8], temp2[11]; + + memcpy(buffer1 , glob->output + 20, 20*sizeof(*buffer1)); + memcpy(buffer1 + 20, glob->output , 20*sizeof(*buffer1)); + + co(36, 40, 35, buffer1, temp1, glob->st1a, glob->st1b, table1); + + if (pred(temp1, glob->st1, 36)) + colmult(glob->pr1, glob->st1, table1a, 36); + + memcpy(buffer2 , glob->history + 4, 4*sizeof(*buffer2)); + memcpy(buffer2 + 4, glob->history , 4*sizeof(*buffer2)); + + co(10, 8, 20, buffer2, temp2, glob->st2a, glob->st2b, table2); + + if (pred(temp2, glob->st2, 10)) + colmult(glob->pr2, glob->st2, table2a, 10); } /* Decode a block (celp) */ -static int ra288_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - const uint8_t * buf, int buf_size) +static int ra288_decode_frame(AVCodecContext * avctx, void *data, + int *data_size, const uint8_t * buf, + int buf_size) { - void *datao; - - if (buf_size < avctx->block_align) - { - av_log(avctx, AV_LOG_ERROR, "ffra288: Error! Input buffer is too small [%d<%d]\n",buf_size,avctx->block_align); + int16_t *out = data; + int x, y; + Real288_internal *glob = avctx->priv_data; + GetBitContext gb; + + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, + "Error! Input buffer is too small [%d<%d]\n", + buf_size, avctx->block_align); return 0; } - datao = data; - data = decode_block(avctx, buf, (signed short *)data, avctx->block_align); + init_get_bits(&gb, buf, avctx->block_align * 8); + + for (x=0; x < 32; x++) { + float gain = amptable[get_bits(&gb, 3)]; + int cb_coef = get_bits(&gb, 6 + (x&1)); + glob->phase = x & 7; + decode(glob, gain, cb_coef); + + for (y=0; y < 5; y++) + *(out++) = 8 * glob->output[glob->phase*5 + y]; - *data_size = (char *)data - (char *)datao; + if (glob->phase == 3) + update(glob); + } + + *data_size = (char *)out - (char *)data; return avctx->block_align; } @@ -251,7 +229,7 @@ AVCodec ra_288_decoder = CODEC_TYPE_AUDIO, CODEC_ID_RA_288, sizeof(Real288_internal), - ra288_decode_init, + NULL, NULL, NULL, ra288_decode_frame, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra288.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ra288.h @@ -22,184 +22,186 @@ #ifndef FFMPEG_RA288_H #define FFMPEG_RA288_H -static const float amptable[8]={ 0.515625, 0.90234375, 1.57910156, 2.76342773, - -0.515625,-0.90234375,-1.57910156,-2.76342773 }; +static const float amptable[8]={ + 0.515625, 0.90234375, 1.57910156, 2.76342773, + -0.515625, -0.90234375, -1.57910156, -2.76342773 +}; -static const float codetable[640]={ - 0.326171875, -1.4404296875, -0.6123046875, -0.8740234375, -1.24658203125, - -2.45703125, -2.23486328125, -0.51025390625, 1.419921875, 1.6201171875, - -1.37646484375, -1.30712890625, -0.462890625, -1.37939453125, -2.1728515625, - -3.26123046875, -0.166015625, 0.7236328125, -0.623046875, 0.6162109375, - -0.2744140625, -3.29931640625, 0.62548828125, 0.08740234375, -0.6220703125, - -1.2265625, -3.4814453125, -2.40478515625, 3.37548828125, 1.17724609375, - -1.2099609375, -0.076171875, 2.28662109375, -1.89111328125, 0, - -4.0078125, 1.044921875, -0.2333984375, -1.35986328125, 0.26025390625, - 0.92236328125, 1.34716796875, 0.67431640625, -3.39599609375, -2.88720703125, - 2.4814453125, -1.201171875, -2.8212890625, 0.87744140625, 0.27734375, - -1.078125, -1.61572265625, -2.20849609375, -3.044921875, -3.66455078125, - -1.32763671875, 2.1279296875, -1.458984375, -0.56103515625, 1.30078125, - 0.61474609375, 0.48583984375, 1.32373046875, -1.203125, -5.0732421875, - 0.8408203125, -3.69580078125, -1.3388671875, 1.06005859375, -1.13720703125, - 0.50390625, 0.36474609375, -0.4189453125, -3.8798828125, -6.27099609375, - 1.5166015625, 2.37109375, -2.04736328125, -1.24072265625, 0.50537109375, - 0.9091796875, -0.46875, -3.236328125, 0.2001953125, 2.8720703125, - -1.21728515625, -1.283203125, -1.953125, -0.029296875, 3.5166015625, - -1.3046875, 0.7060546875, 0.75, -1.87060546875, 0.60205078125, - -2.5888671875, 3.375, 0.77587890625, -2.04443359375, 1.78955078125, - -1.6875, -3.9892578125, -3.76416015625, 0.67578125, 2.2939453125, - -2.29443359375, -3.03173828125, -5.45703125, 3.95703125, 8.2177734375, - 0.4541015625, 3.419921875, 0.61962890625, -4.38330078125, 1.25341796875, - 2.27001953125, 5.763671875, 1.68017578125, -2.76220703125, 0.58544921875, - 1.2412109375, -0.08935546875, -4.32568359375, -3.89453125, 1.5771484375, - -1.40234375, -0.98193359375, -4.74267578125, -4.09423828125, 6.33935546875, - 1.5068359375, 1.044921875, -1.796875, -4.70849609375, -1.4140625, - -3.71533203125, 3.18115234375, -1.11474609375, -1.2314453125, 3.091796875, - -1.62744140625, -2.744140625, -4.4580078125, -5.43505859375, 2.70654296875, - -0.19873046875, -3.28173828125, -8.5283203125, -1.41064453125, 5.6484375, - 1.802734375, 3.318359375, -0.1279296875, -5.2958984375, -0.90625, - 3.55224609375, 6.544921875, -1.45947265625, -5.17333984375, 2.41015625, - 0.119140625, -1.08349609375, 1.296875, 1.84375, -2.642578125, - -1.97412109375, -2.8974609375, 1.04052734375, 0.42138671875, -1.3994140625, - -1.6123046875, 0.85107421875, -0.9794921875, -0.0625, -1.001953125, - -3.10595703125, 1.6318359375, -0.77294921875, -0.01025390625, 0.5576171875, - -1.87353515625, -0.89404296875, 3.12353515625, 1.24267578125, -1.390625, - -4.556640625, -3.1875, 2.59228515625, 0.9697265625, -1.09619140625, - -2.1923828125, 0.365234375, 0.94482421875, -1.47802734375, -0.24072265625, - -4.51904296875, 2.6201171875, 1.55908203125, -2.19384765625, 0.87109375, - 2.3359375, -0.1806640625, 0.9111328125, 0.51611328125, -0.92236328125, - 3.5849609375, -1.3134765625, -1.25830078125, 0.330078125, -0.29833984375, - -0.2451171875, 1.09130859375, -0.9033203125, -0.86767578125, -1.00048828125, - 0.49365234375, 1.89453125, -1.20361328125, 1.07861328125, -0.07421875, - 1.265625, 1.38134765625, 2.728515625, 1.38623046875, -3.5673828125, - -1.48876953125, -2.4013671875, 2.90771484375, 4.49267578125, -2.17138671875, - 0.34033203125, 1.908203125, 2.8310546875, -2.17333984375, -2.267578125, - -1.03564453125, 2.658203125, -1.2548828125, 0.15673828125, -0.5869140625, - 1.3896484375, -1.0185546875, 1.724609375, 0.2763671875, -0.345703125, - -2.08935546875, 0.4638671875, 2.431640625, 1.83056640625, 0.220703125, - -1.212890625, 1.7099609375, 0.83935546875, -0.0830078125, 0.1162109375, - -1.67724609375, 0.12841796875, 1.0322265625, -0.97900390625, 1.15283203125, - -3.5830078125, -0.58984375, 4.56396484375, -0.59375, -1.95947265625, - -6.5908203125, -0.21435546875, 3.919921875, -2.06640625, 0.17626953125, - -1.82080078125, 2.65283203125, 0.978515625, -2.30810546875, -0.61474609375, - -1.9462890625, 3.78076171875, 4.11572265625, -1.80224609375, -0.48193359375, - 2.5380859375, -0.20654296875, 0.5615234375, -0.62548828125, 0.3984375, - 3.61767578125, 2.00634765625, -1.92822265625, 1.3134765625, 0.0146484384313, - 0.6083984375, 1.49169921875, -0.01708984375, -0.6689453125, -0.1201171875, - -0.72705078125, 2.75146484375, -0.3310546875, -1.28271484375, 1.5478515625, - 2.3583984375, -2.23876953125, 0.98046875, -0.5185546875, 0.39013671875, - -0.06298828125, 0.35009765625, 2.2431640625, 7.29345703125, 5.2275390625, - 0.20361328125, 1.34716796875, 0.9033203125, -2.46923828125, -0.56298828125, - -1.89794921875, 3.59423828125, -2.81640625, 2.09228515625, 0.3251953125, - 0.70458984375, -0.4580078125, 0.009765625, -1.03466796875, -0.82861328125, - -1.8125, -1.6611328125, -1.080078125, 0.0537109375, 1.04296875, - -1.44140625, 0.005859375, -0.765625, -1.708984375, -0.90576171875, - -0.64208984375, -0.84521484375, 0.56640625, -0.2724609375, 0.83447265625, - 0.04296875, -2.23095703125, 0.0947265625, -0.2216796875, -1.44384765625, - -1.38623046875, -0.8134765625, -0.13330078125, 1.017578125, -0.07568359375, - -0.09228515625, -1.16015625, 0.81201171875, -0.5078125, -1.19580078125, - -1.3876953125, -0.66845703125, 0.310546875, -0.12109375, -1.30712890625, - 0.74072265625, 0.03857421875, -1.47119140625, -1.79150390625, -0.47509765625, - 0.93408203125, -1.21728515625, -2.59375, -0.36572265625, 0.62060546875, - -1.41748046875, -1.623046875, -1.833984375, -1.8017578125, -0.89306640625, - -1.42236328125, -0.75537109375, -1.34765625, -0.6865234375, 0.548828125, - 0.900390625, -0.8955078125, 0.22265625, 0.3447265625, -2.0859375, - 0.22802734375, -2.078125, -0.93212890625, 0.74267578125, 0.5537109375, - -0.06201171875, -0.4853515625, -0.31103515625, -0.72802734375, -3.1708984375, - 0.42626953125, -0.99853515625, -1.869140625, -1.36328125, -0.2822265625, - 1.12841796875, -0.88720703125, 1.28515625, -1.490234375, 0.9609375, - 0.31298828125, 0.5830078125, 0.92431640625, 2.00537109375, 3.0966796875, - -0.02197265625, 0.5849609375, 1.0546875, -0.70751953125, 1.07568359375, - -0.978515625, 0.83642578125, 1.7177734375, 1.294921875, 2.07568359375, - 1.43359375, -1.9375, 0.625, 0.06396484375, -0.720703125, - 1.38037109375, 0.00390625, -0.94140625, 1.2978515625, 1.71533203125, - 1.56201171875, -0.3984375, 1.31201171875, -0.85009765625, -0.68701171875, - 1.439453125, 1.96728515625, 0.1923828125, -0.12353515625, 0.6337890625, - 2.0927734375, 0.02490234375, -2.20068359375, -0.015625, -0.32177734375, - 1.90576171875, 2.7568359375, -2.728515625, -1.265625, 2.78662109375, - -0.2958984375, 0.6025390625, -0.78466796875, -2.53271484375, 0.32421875, - -0.25634765625, 1.767578125, -1.0703125, -1.23388671875, 0.83349609375, - 2.09814453125, -1.58740234375, -1.11474609375, 0.396484375, -1.10546875, - 2.81494140625, 0.2578125, -1.60498046875, 0.66015625, 0.81640625, - 1.33544921875, 0.60595703125, -0.53857421875, -1.59814453125, -1.66357421875, - 1.96923828125, 0.8046875, -1.44775390625, -0.5732421875, 0.705078125, - 0.0361328125, 0.4482421875, 0.97607421875, 0.44677734375, -0.5009765625, - -1.21875, -0.78369140625, 0.9931640625, 1.4404296875, 0.11181640625, - -1.05859375, 0.99462890625, 0.00732421921566,-0.6171875, -0.1015625, - -1.734375, 0.7470703125, 0.28369140625, 0.72802734375, 0.4697265625, - -1.27587890625, -1.1416015625, 1.76806640625, -0.7265625, -1.06689453125, - -0.85302734375, 0.03955078125, 2.7041015625, 0.69921875, -1.10205078125, - -0.49755859375, 0.42333984375, 0.1044921875, -1.115234375, -0.7373046875, - -0.822265625, 1.375, -0.11181640625, 1.24560546875, -0.67822265625, - 1.32177734375, 0.24609375, 0.23388671875, 1.35888671875, -0.49267578125, - 1.22900390625, -0.72607421875, -0.779296875, 0.30322265625, 0.94189453125, - -0.072265625, 1.0771484375, -2.09375, 0.630859375, -0.68408203125, - -0.25732421875, 0.60693359375, -1.33349609375, 0.93212890625, 0.625, - 1.04931640625, -0.73291015625, 1.80078125, 0.2978515625, -2.24169921875, - 1.6142578125, -1.64501953125, 0.91552734375, 1.775390625, -0.59423828125, - 1.2568359375, 1.22705078125, 0.70751953125, -1.5009765625, -2.43115234375, - 0.3974609375, 0.8916015625, -1.21923828125, 2.0673828125, -1.99072265625, - 0.8125, -0.107421875, 1.6689453125, 0.4892578125, 0.54443359375, - 0.38134765625, 0.8095703125, 1.91357421875, 2.9931640625, 1.533203125, - 0.560546875, 1.98486328125, 0.740234375, 0.39794921875, 0.09716796875, - 0.58154296875, 1.21533203125, 1.25048828125, 1.18212890625, 1.19287109375, - 0.3759765625, -2.88818359375, 2.69287109375, -0.1796875, -1.56201171875, - 0.5810546875, 0.51123046875, 1.8271484375, 3.38232421875, -1.02001953125, - 0.142578125, 1.51318359375, 2.103515625, -0.3701171875, -1.19873046875, - 0.25537109375, 1.91455078125, 1.974609375, 0.6767578125, 0.04150390625, - 2.13232421875, 0.4912109375, -0.611328125, -0.7158203125, -0.67529296875, - 1.880859375, 0.77099609375, -0.03759765625, 1.0078125, 0.423828125, - 2.49462890625, 1.42529296875, -0.0986328125, 0.17529296875, -0.24853515625, - 1.7822265625, 1.5654296875, 1.12451171875, 0.82666015625, 0.6328125, - 1.41845703125, -1.90771484375, 0.11181640625, -0.583984375, -1.138671875, - 2.91845703125, -1.75048828125, 0.39306640625, 1.86767578125, -1.5322265625, - 1.8291015625, -0.2958984375, 0.02587890625, -0.13134765625, -1.61181640625, - 0.2958984375, 0.9853515625, -0.642578125, 1.984375, 0.1943359375 +static const float codetable[128][5]={ +{ 0.326171875, -1.4404296875, -0.6123046875, -0.8740234375, -1.24658203125}, +{-2.45703125, -2.23486328125, -0.51025390625, 1.419921875, 1.6201171875 }, +{-1.37646484375, -1.30712890625, -0.462890625, -1.37939453125, -2.1728515625 }, +{-3.26123046875, -0.166015625, 0.7236328125, -0.623046875, 0.6162109375 }, +{-0.2744140625, -3.29931640625, 0.62548828125, 0.08740234375, -0.6220703125 }, +{-1.2265625, -3.4814453125, -2.40478515625, 3.37548828125, 1.17724609375}, +{-1.2099609375, -0.076171875, 2.28662109375, -1.89111328125, 0 }, +{-4.0078125, 1.044921875, -0.2333984375, -1.35986328125, 0.26025390625}, +{ 0.92236328125, 1.34716796875, 0.67431640625, -3.39599609375, -2.88720703125}, +{ 2.4814453125, -1.201171875, -2.8212890625, 0.87744140625, 0.27734375 }, +{-1.078125, -1.61572265625, -2.20849609375, -3.044921875, -3.66455078125}, +{-1.32763671875, 2.1279296875, -1.458984375, -0.56103515625, 1.30078125 }, +{ 0.61474609375, 0.48583984375, 1.32373046875, -1.203125, -5.0732421875 }, +{ 0.8408203125, -3.69580078125, -1.3388671875, 1.06005859375, -1.13720703125}, +{ 0.50390625, 0.36474609375, -0.4189453125, -3.8798828125, -6.27099609375}, +{ 1.5166015625, 2.37109375, -2.04736328125, -1.24072265625, 0.50537109375}, +{ 0.9091796875, -0.46875, -3.236328125, 0.2001953125, 2.8720703125 }, +{-1.21728515625, -1.283203125, -1.953125, -0.029296875, 3.5166015625 }, +{-1.3046875, 0.7060546875, 0.75, -1.87060546875, 0.60205078125}, +{-2.5888671875, 3.375, 0.77587890625, -2.04443359375, 1.78955078125}, +{-1.6875, -3.9892578125, -3.76416015625, 0.67578125, 2.2939453125 }, +{-2.29443359375, -3.03173828125, -5.45703125, 3.95703125, 8.2177734375 }, +{ 0.4541015625, 3.419921875, 0.61962890625, -4.38330078125, 1.25341796875}, +{ 2.27001953125, 5.763671875, 1.68017578125, -2.76220703125, 0.58544921875}, +{ 1.2412109375, -0.08935546875, -4.32568359375, -3.89453125, 1.5771484375 }, +{-1.40234375, -0.98193359375, -4.74267578125, -4.09423828125, 6.33935546875}, +{ 1.5068359375, 1.044921875, -1.796875, -4.70849609375, -1.4140625 }, +{-3.71533203125, 3.18115234375, -1.11474609375, -1.2314453125, 3.091796875 }, +{-1.62744140625, -2.744140625, -4.4580078125, -5.43505859375, 2.70654296875}, +{-0.19873046875, -3.28173828125, -8.5283203125, -1.41064453125, 5.6484375 }, +{ 1.802734375, 3.318359375, -0.1279296875, -5.2958984375, -0.90625 }, +{ 3.55224609375, 6.544921875, -1.45947265625, -5.17333984375, 2.41015625 }, +{ 0.119140625, -1.08349609375, 1.296875, 1.84375, -2.642578125 }, +{-1.97412109375, -2.8974609375, 1.04052734375, 0.42138671875, -1.3994140625 }, +{-1.6123046875, 0.85107421875, -0.9794921875, -0.0625, -1.001953125 }, +{-3.10595703125, 1.6318359375, -0.77294921875, -0.01025390625, 0.5576171875 }, +{-1.87353515625, -0.89404296875, 3.12353515625, 1.24267578125, -1.390625 }, +{-4.556640625, -3.1875, 2.59228515625, 0.9697265625, -1.09619140625}, +{-2.1923828125, 0.365234375, 0.94482421875, -1.47802734375, -0.24072265625}, +{-4.51904296875, 2.6201171875, 1.55908203125, -2.19384765625, 0.87109375 }, +{ 2.3359375, -0.1806640625, 0.9111328125, 0.51611328125, -0.92236328125}, +{ 3.5849609375, -1.3134765625, -1.25830078125, 0.330078125, -0.29833984375}, +{-0.2451171875, 1.09130859375, -0.9033203125, -0.86767578125, -1.00048828125}, +{ 0.49365234375, 1.89453125, -1.20361328125, 1.07861328125, -0.07421875 }, +{ 1.265625, 1.38134765625, 2.728515625, 1.38623046875, -3.5673828125 }, +{-1.48876953125, -2.4013671875, 2.90771484375, 4.49267578125, -2.17138671875}, +{ 0.34033203125, 1.908203125, 2.8310546875, -2.17333984375, -2.267578125 }, +{-1.03564453125, 2.658203125, -1.2548828125, 0.15673828125, -0.5869140625 }, +{ 1.3896484375, -1.0185546875, 1.724609375, 0.2763671875, -0.345703125 }, +{-2.08935546875, 0.4638671875, 2.431640625, 1.83056640625, 0.220703125 }, +{-1.212890625, 1.7099609375, 0.83935546875, -0.0830078125, 0.1162109375 }, +{-1.67724609375, 0.12841796875, 1.0322265625, -0.97900390625, 1.15283203125}, +{-3.5830078125, -0.58984375, 4.56396484375, -0.59375, -1.95947265625}, +{-6.5908203125, -0.21435546875, 3.919921875, -2.06640625, 0.17626953125}, +{-1.82080078125, 2.65283203125, 0.978515625, -2.30810546875, -0.61474609375}, +{-1.9462890625, 3.78076171875, 4.11572265625, -1.80224609375, -0.48193359375}, +{ 2.5380859375, -0.20654296875, 0.5615234375, -0.62548828125, 0.3984375 }, +{ 3.61767578125, 2.00634765625, -1.92822265625, 1.3134765625, 0.0146484384313}, +{ 0.6083984375, 1.49169921875, -0.01708984375, -0.6689453125, -0.1201171875 }, +{-0.72705078125, 2.75146484375, -0.3310546875, -1.28271484375, 1.5478515625 }, +{ 2.3583984375, -2.23876953125, 0.98046875, -0.5185546875, 0.39013671875}, +{-0.06298828125, 0.35009765625, 2.2431640625, 7.29345703125, 5.2275390625 }, +{ 0.20361328125, 1.34716796875, 0.9033203125, -2.46923828125, -0.56298828125}, +{-1.89794921875, 3.59423828125, -2.81640625, 2.09228515625, 0.3251953125 }, +{ 0.70458984375, -0.4580078125, 0.009765625, -1.03466796875, -0.82861328125}, +{-1.8125, -1.6611328125, -1.080078125, 0.0537109375, 1.04296875 }, +{-1.44140625, 0.005859375, -0.765625, -1.708984375, -0.90576171875}, +{-0.64208984375, -0.84521484375, 0.56640625, -0.2724609375, 0.83447265625}, +{ 0.04296875, -2.23095703125, 0.0947265625, -0.2216796875, -1.44384765625}, +{-1.38623046875, -0.8134765625, -0.13330078125, 1.017578125, -0.07568359375}, +{-0.09228515625, -1.16015625, 0.81201171875, -0.5078125, -1.19580078125}, +{-1.3876953125, -0.66845703125, 0.310546875, -0.12109375, -1.30712890625}, +{ 0.74072265625, 0.03857421875, -1.47119140625, -1.79150390625, -0.47509765625}, +{ 0.93408203125, -1.21728515625, -2.59375, -0.36572265625, 0.62060546875}, +{-1.41748046875, -1.623046875, -1.833984375, -1.8017578125, -0.89306640625}, +{-1.42236328125, -0.75537109375, -1.34765625, -0.6865234375, 0.548828125 }, +{ 0.900390625, -0.8955078125, 0.22265625, 0.3447265625, -2.0859375 }, +{ 0.22802734375, -2.078125, -0.93212890625, 0.74267578125, 0.5537109375 }, +{-0.06201171875, -0.4853515625, -0.31103515625, -0.72802734375, -3.1708984375 }, +{ 0.42626953125, -0.99853515625, -1.869140625, -1.36328125, -0.2822265625 }, +{ 1.12841796875, -0.88720703125, 1.28515625, -1.490234375, 0.9609375 }, +{ 0.31298828125, 0.5830078125, 0.92431640625, 2.00537109375, 3.0966796875 }, +{-0.02197265625, 0.5849609375, 1.0546875, -0.70751953125, 1.07568359375}, +{-0.978515625, 0.83642578125, 1.7177734375, 1.294921875, 2.07568359375}, +{ 1.43359375, -1.9375, 0.625, 0.06396484375, -0.720703125 }, +{ 1.38037109375, 0.00390625, -0.94140625, 1.2978515625, 1.71533203125}, +{ 1.56201171875, -0.3984375, 1.31201171875, -0.85009765625, -0.68701171875}, +{ 1.439453125, 1.96728515625, 0.1923828125, -0.12353515625, 0.6337890625 }, +{ 2.0927734375, 0.02490234375, -2.20068359375, -0.015625, -0.32177734375}, +{ 1.90576171875, 2.7568359375, -2.728515625, -1.265625, 2.78662109375}, +{-0.2958984375, 0.6025390625, -0.78466796875, -2.53271484375, 0.32421875 }, +{-0.25634765625, 1.767578125, -1.0703125, -1.23388671875, 0.83349609375}, +{ 2.09814453125, -1.58740234375, -1.11474609375, 0.396484375, -1.10546875 }, +{ 2.81494140625, 0.2578125, -1.60498046875, 0.66015625, 0.81640625 }, +{ 1.33544921875, 0.60595703125, -0.53857421875, -1.59814453125, -1.66357421875}, +{ 1.96923828125, 0.8046875, -1.44775390625, -0.5732421875, 0.705078125 }, +{ 0.0361328125, 0.4482421875, 0.97607421875, 0.44677734375, -0.5009765625 }, +{-1.21875, -0.78369140625, 0.9931640625, 1.4404296875, 0.11181640625}, +{-1.05859375, 0.99462890625,0.00732421921566,-0.6171875, -0.1015625 }, +{-1.734375, 0.7470703125, 0.28369140625, 0.72802734375, 0.4697265625 }, +{-1.27587890625, -1.1416015625, 1.76806640625, -0.7265625, -1.06689453125}, +{-0.85302734375, 0.03955078125, 2.7041015625, 0.69921875, -1.10205078125}, +{-0.49755859375, 0.42333984375, 0.1044921875, -1.115234375, -0.7373046875 }, +{-0.822265625, 1.375, -0.11181640625, 1.24560546875, -0.67822265625}, +{ 1.32177734375, 0.24609375, 0.23388671875, 1.35888671875, -0.49267578125}, +{ 1.22900390625, -0.72607421875, -0.779296875, 0.30322265625, 0.94189453125}, +{-0.072265625, 1.0771484375, -2.09375, 0.630859375, -0.68408203125}, +{-0.25732421875, 0.60693359375, -1.33349609375, 0.93212890625, 0.625 }, +{ 1.04931640625, -0.73291015625, 1.80078125, 0.2978515625, -2.24169921875}, +{ 1.6142578125, -1.64501953125, 0.91552734375, 1.775390625, -0.59423828125}, +{ 1.2568359375, 1.22705078125, 0.70751953125, -1.5009765625, -2.43115234375}, +{ 0.3974609375, 0.8916015625, -1.21923828125, 2.0673828125, -1.99072265625}, +{ 0.8125, -0.107421875, 1.6689453125, 0.4892578125, 0.54443359375}, +{ 0.38134765625, 0.8095703125, 1.91357421875, 2.9931640625, 1.533203125 }, +{ 0.560546875, 1.98486328125, 0.740234375, 0.39794921875, 0.09716796875}, +{ 0.58154296875, 1.21533203125, 1.25048828125, 1.18212890625, 1.19287109375}, +{ 0.3759765625, -2.88818359375, 2.69287109375, -0.1796875, -1.56201171875}, +{ 0.5810546875, 0.51123046875, 1.8271484375, 3.38232421875, -1.02001953125}, +{ 0.142578125, 1.51318359375, 2.103515625, -0.3701171875, -1.19873046875}, +{ 0.25537109375, 1.91455078125, 1.974609375, 0.6767578125, 0.04150390625}, +{ 2.13232421875, 0.4912109375, -0.611328125, -0.7158203125, -0.67529296875}, +{ 1.880859375, 0.77099609375, -0.03759765625, 1.0078125, 0.423828125 }, +{ 2.49462890625, 1.42529296875, -0.0986328125, 0.17529296875, -0.24853515625}, +{ 1.7822265625, 1.5654296875, 1.12451171875, 0.82666015625, 0.6328125 }, +{ 1.41845703125, -1.90771484375, 0.11181640625, -0.583984375, -1.138671875 }, +{ 2.91845703125, -1.75048828125, 0.39306640625, 1.86767578125, -1.5322265625 }, +{ 1.8291015625, -0.2958984375, 0.02587890625, -0.13134765625, -1.61181640625}, +{ 0.2958984375, 0.9853515625, -0.642578125, 1.984375, 0.1943359375 } }; static const float table1[111]={ - 0.576690972, 0.580838025, 0.585013986, 0.589219987, 0.59345597, 0.597723007, - 0.602020264, 0.606384277, 0.610748291, 0.615142822, 0.619598389, 0.624084473, - 0.628570557, 0.633117676, 0.637695313, 0.642272949, 0.646911621, 0.651580811, - 0.656280518, 0.66104126, 0.665802002, 0.670593262, 0.675445557, 0.680328369, - 0.685241699, 0.690185547, 0.695159912, 0.700164795, 0.705230713, 0.710327148, - 0.715454102, 0.720611572, 0.725830078, 0.731048584, 0.736328125, 0.741638184, - 0.747009277, 0.752380371, 0.7578125, 0.763305664, 0.768798828, 0.774353027, - 0.779937744, 0.785583496, 0.791229248, 0.796936035, 0.802703857, 0.808502197, - 0.814331055, 0.820220947, 0.826141357, 0.832092285, 0.838104248, 0.844146729, - 0.850250244, 0.856384277, 0.862548828, 0.868774414, 0.875061035, 0.881378174, - 0.88772583, 0.894134521, 0.900604248, 0.907104492, 0.913635254, 0.920227051, - 0.926879883, 0.933563232, 0.940307617, 0.94708252, 0.953918457, 0.96081543, - 0.96774292, 0.974731445, 0.981781006, 0.988861084, 0.994842529, 0.998565674, - 0.999969482, 0.99911499, 0.996002197, 0.990600586, 0.982910156, 0.973022461, - 0.960876465, 0.946533203, 0.930053711, 0.911437988, 0.89074707, 0.868041992, - 0.843322754, 0.816680908, 0.788208008, 0.757904053, 0.725891113, 0.692199707, - 0.656921387, 0.620178223, 0.582000732, 0.542480469, 0.501739502, 0.459838867, - 0.416900635, 0.373016357, 0.328277588, 0.282775879, 0.236663818, 0.189971924, - 0.142852783, 0.0954284668, 0.0477600098 + 0.576690972, 0.580838025, 0.585013986, 0.589219987, 0.59345597, 0.597723007, + 0.602020264, 0.606384277, 0.610748291, 0.615142822, 0.619598389, 0.624084473, + 0.628570557, 0.633117676, 0.637695313, 0.642272949, 0.646911621, 0.651580811, + 0.656280518, 0.66104126, 0.665802002, 0.670593262, 0.675445557, 0.680328369, + 0.685241699, 0.690185547, 0.695159912, 0.700164795, 0.705230713, 0.710327148, + 0.715454102, 0.720611572, 0.725830078, 0.731048584, 0.736328125, 0.741638184, + 0.747009277, 0.752380371, 0.7578125, 0.763305664, 0.768798828, 0.774353027, + 0.779937744, 0.785583496, 0.791229248, 0.796936035, 0.802703857, 0.808502197, + 0.814331055, 0.820220947, 0.826141357, 0.832092285, 0.838104248, 0.844146729, + 0.850250244, 0.856384277, 0.862548828, 0.868774414, 0.875061035, 0.881378174, + 0.88772583, 0.894134521, 0.900604248, 0.907104492, 0.913635254, 0.920227051, + 0.926879883, 0.933563232, 0.940307617, 0.94708252, 0.953918457, 0.96081543, + 0.96774292, 0.974731445, 0.981781006, 0.988861084, 0.994842529, 0.998565674, + 0.999969482, 0.99911499, 0.996002197, 0.990600586, 0.982910156, 0.973022461, + 0.960876465, 0.946533203, 0.930053711, 0.911437988, 0.89074707, 0.868041992, + 0.843322754, 0.816680908, 0.788208008, 0.757904053, 0.725891113, 0.692199707, + 0.656921387, 0.620178223, 0.582000732, 0.542480469, 0.501739502, 0.459838867, + 0.416900635, 0.373016357, 0.328277588, 0.282775879, 0.236663818, 0.189971924, + 0.142852783, 0.0954284668,0.0477600098 }; static const float table2[38]={ - 0.505699992, 0.524200022, 0.54339999, 0.563300014, 0.583953857, 0.60534668, - 0.627502441, 0.650482178, 0.674316406, 0.699005127, 0.724578857, 0.75112915, - 0.778625488, 0.807128906, 0.836669922, 0.86730957, 0.899078369, 0.932006836, - 0.961486816, 0.982757568, 0.995635986, 1, 0.995819092, 0.983154297, - 0.96206665, 0.932769775, 0.895507813, 0.850585938, 0.798400879, 0.739379883, - 0.674072266, 0.602996826, 0.526763916, 0.446014404, 0.361480713, 0.273834229, - 0.183868408, 0.0923461914 + 0.505699992, 0.524200022, 0.54339999, 0.563300014, 0.583953857, 0.60534668, + 0.627502441, 0.650482178, 0.674316406, 0.699005127, 0.724578857, 0.75112915, + 0.778625488, 0.807128906, 0.836669922, 0.86730957, 0.899078369, 0.932006836, + 0.961486816, 0.982757568, 0.995635986, 1, 0.995819092, 0.983154297, + 0.96206665, 0.932769775, 0.895507813, 0.850585938, 0.798400879, 0.739379883, + 0.674072266, 0.602996826, 0.526763916, 0.446014404, 0.361480713, 0.273834229, + 0.183868408, 0.0923461914 }; static const float table1a[36]={ - 0.98828125, 0.976699829, 0.965254128, 0.953942537, 0.942763507, 0.931715488, - 0.920796931, 0.910006344, 0.899342179, 0.888803005, 0.878387332, 0.868093729, - 0.857920766, 0.847867012, 0.837931097, 0.828111589, 0.818407178, 0.808816493, - 0.799338162, 0.789970934, 0.780713439, 0.771564424, 0.762522638, 0.753586829, - 0.744755745, 0.736028135, 0.727402806, 0.718878567, 0.710454226, 0.702128589, - 0.693900526, 0.685768902, 0.677732527, 0.669790328, 0.66194123, 0.654184103 + 0.98828125, 0.976699829, 0.965254128, 0.953942537, 0.942763507, 0.931715488, + 0.920796931, 0.910006344, 0.899342179, 0.888803005, 0.878387332, 0.868093729, + 0.857920766, 0.847867012, 0.837931097, 0.828111589, 0.818407178, 0.808816493, + 0.799338162, 0.789970934, 0.780713439, 0.771564424, 0.762522638, 0.753586829, + 0.744755745, 0.736028135, 0.727402806, 0.718878567, 0.710454226, 0.702128589, + 0.693900526, 0.685768902, 0.677732527, 0.669790328, 0.66194123, 0.654184103 }; static const float table2a[10]={ - 0.90625, 0.821289063, 0.74432373, 0.674499512, 0.61126709, - 0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227 + 0.90625, 0.821289063, 0.74432373, 0.674499512, 0.61126709, + 0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227 }; #endif /* FFMPEG_RA288_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ratecontrol.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ratecontrol.c @@ -67,7 +67,7 @@ int ff_rate_control_init(MpegEncContext *s) RateControlContext *rcc= &s->rc_context; int i; const char *error = NULL; - static const char *const_names[]={ + static const char * const const_names[]={ "PI", "E", "iTex", @@ -99,7 +99,7 @@ int ff_rate_control_init(MpegEncContext *s) (void *)qp2bits, NULL }; - static const char *func1_names[]={ + static const char * const func1_names[]={ "bits2qp", "qp2bits", NULL diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/roqvideoenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/roqvideoenc.c @@ -911,6 +911,8 @@ static void roq_encode_video(RoqContext *enc) reconstruct_and_encode_image(enc, &tempData, enc->width, enc->height, enc->width*enc->height/64); + enc->avctx->coded_frame = enc->current_frame; + /* Rotate frame history */ FFSWAP(AVFrame *, enc->current_frame, enc->last_frame); FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/rv10.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/rv10.c @@ -265,7 +265,7 @@ void rv20_encode_picture_header(MpegEncContext *s, int picture_number){ put_bits(&s->pb, 1, 0); /* unknown bit */ put_bits(&s->pb, 5, s->qscale); - put_bits(&s->pb, 8, picture_number&0xFF); //FIXME wrong, but correct is not known + put_sbits(&s->pb, 8, picture_number); //FIXME wrong, but correct is not known s->mb_x= s->mb_y= 0; ff_h263_encode_mba(s); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/snow.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/snow.c @@ -363,7 +363,7 @@ static const uint8_t obmc4[16]={ //error:0.000000 }; -static const uint8_t *obmc_tab[4]={ +static const uint8_t * const obmc_tab[4]={ obmc32, obmc16, obmc8, obmc4 }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/sonic.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/sonic.c @@ -481,7 +481,7 @@ static void modified_levinson_durbin(int *window, int window_entries, } #endif /* CONFIG_ENCODERS */ -static int samplerate_table[] = +static const int samplerate_table[] = { 44100, 22050, 11025, 96000, 48000, 32000, 24000, 16000, 8000 }; #ifdef CONFIG_ENCODERS diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/svq3.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/svq3.c @@ -835,6 +835,7 @@ static int svq3_decode_frame (AVCodecContext *avctx, if (buf_size == 0) { if (s->next_picture_ptr && !s->low_delay) { *(AVFrame *) data = *(AVFrame *) &s->next_picture; + s->next_picture_ptr= NULL; *data_size = sizeof(AVFrame); } return 0; @@ -851,9 +852,9 @@ static int svq3_decode_frame (AVCodecContext *avctx, s->picture_number = h->slice_num; if(avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d\n", + av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n", av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag, - s->adaptive_quant, s->qscale + s->adaptive_quant, s->qscale, h->slice_num ); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/tiertexseqv.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/tiertexseqv.c @@ -32,8 +32,6 @@ typedef struct SeqVideoContext { AVCodecContext *avctx; AVFrame frame; - unsigned int palette[256]; - unsigned char block[8 * 8]; } SeqVideoContext; @@ -72,22 +70,23 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned const unsigned char *color_table; int b, i, len, bits; GetBitContext gb; + unsigned char block[8 * 8]; len = *src++; if (len & 0x80) { switch (len & 3) { case 1: - src = seq_unpack_rle_block(src, seq->block, sizeof(seq->block)); + src = seq_unpack_rle_block(src, block, sizeof(block)); for (b = 0; b < 8; b++) { - memcpy(dst, &seq->block[b * 8], 8); + memcpy(dst, &block[b * 8], 8); dst += seq->frame.linesize[0]; } break; case 2: - src = seq_unpack_rle_block(src, seq->block, sizeof(seq->block)); + src = seq_unpack_rle_block(src, block, sizeof(block)); for (i = 0; i < 8; i++) { for (b = 0; b < 8; b++) - dst[b * seq->frame.linesize[0]] = seq->block[i * 8 + b]; + dst[b * seq->frame.linesize[0]] = block[i * 8 + b]; ++dst; } break; @@ -139,16 +138,17 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int int flags, i, j, x, y, op; unsigned char c[3]; unsigned char *dst; + uint32_t *palette; flags = *data++; if (flags & 1) { + palette = (uint32_t *)seq->frame.data[1]; for (i = 0; i < 256; i++) { for (j = 0; j < 3; j++, data++) c[j] = (*data << 2) | (*data >> 4); - seq->palette[i] = AV_RB24(c); + palette[i] = AV_RB24(c); } - memcpy(seq->frame.data[1], seq->palette, sizeof(seq->palette)); seq->frame.palette_has_changed = 1; } @@ -185,7 +185,7 @@ static av_cold int seqvideo_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int seqvideo_decode_frame(AVCodecContext *avctx, +static int seqvideo_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { @@ -207,7 +207,7 @@ static av_cold int seqvideo_decode_frame(AVCodecContext *avctx, return buf_size; } -static int seqvideo_decode_end(AVCodecContext *avctx) +static av_cold int seqvideo_decode_end(AVCodecContext *avctx) { SeqVideoContext *seq = avctx->priv_data; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/truemotion1.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/truemotion1.c @@ -117,7 +117,7 @@ typedef struct comp_types { } comp_types; /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */ -static comp_types compression_types[17] = { +static const comp_types compression_types[17] = { { ALGO_NOP, 0, 0, 0 }, { ALGO_RGB16V, 4, 4, BLOCK_4x4 }, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/truemotion1data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/truemotion1data.h @@ -46,10 +46,10 @@ static const int16_t cdt3[8] = { 0, -2, 2, -8, 8, -18, 18, -40 }; static const int16_t fat_cdt3[8] = { 0, 40, 80, -76, 160, -154, 236, -236 }; /* all the delta tables to choose from, at all 4 delta levels */ -static const int16_t *ydts[] = { ydt1, ydt2, ydt3, ydt4, NULL }; -static const int16_t *fat_ydts[] = { fat_ydt3, fat_ydt3, fat_ydt3, fat_ydt4, NULL }; -static const int16_t *cdts[] = { cdt1, cdt1, cdt2, cdt3, NULL }; -static const int16_t *fat_cdts[] = { fat_cdt2, fat_cdt2, fat_cdt2, fat_cdt3, NULL }; +static const int16_t * const ydts[] = { ydt1, ydt2, ydt3, ydt4, NULL }; +static const int16_t * const fat_ydts[] = { fat_ydt3, fat_ydt3, fat_ydt3, fat_ydt4, NULL }; +static const int16_t * const cdts[] = { cdt1, cdt1, cdt2, cdt3, NULL }; +static const int16_t * const fat_cdts[] = { fat_cdt2, fat_cdt2, fat_cdt2, fat_cdt3, NULL }; static const uint8_t pc_tbl2[] = { 0x8,0x00,0x00,0x00,0x00, @@ -828,6 +828,6 @@ static const uint8_t pc_tbl4[] = { 0x2,0x77 }; -static const uint8_t *tables[] = { pc_tbl2, pc_tbl3, pc_tbl4 }; +static const uint8_t * const tables[] = { pc_tbl2, pc_tbl3, pc_tbl4 }; #endif /* FFMPEG_TRUEMOTION1DATA_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/truespeech_data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/truespeech_data.h @@ -66,7 +66,7 @@ static const int16_t ts_cb_7[8] = { 0xCEF0, 0xE4F9, 0xF6BB, 0x0646, 0x14F5, 0x23FF, 0x356F, 0x4A8D, }; -static const int16_t *ts_codebook[8] = { +static const int16_t * const ts_codebook[8] = { ts_cb_0, ts_cb_1, ts_cb_2, ts_cb_3, ts_cb_4, ts_cb_5, ts_cb_6, ts_cb_7 }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/tta.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/tta.c @@ -76,7 +76,7 @@ static const uint32_t shift_1[] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; -static const uint32_t *shift_16 = shift_1 + 4; +static const uint32_t * const shift_16 = shift_1 + 4; #endif #define MAX_ORDER 16 @@ -87,7 +87,7 @@ typedef struct TTAFilter { int32_t dl[MAX_ORDER]; } TTAFilter; -static int32_t ttafilter_configs[4][2] = { +static const int32_t ttafilter_configs[4][2] = { {10, 1}, {9, 1}, {10, 1}, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ulti.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/ulti.c @@ -56,13 +56,13 @@ static av_cold int ulti_decode_init(AVCodecContext *avctx) return 0; } -static int block_coords[8] = // 4x4 block coords in 8x8 superblock +static const int block_coords[8] = // 4x4 block coords in 8x8 superblock { 0, 0, 0, 4, 4, 4, 4, 0}; -static int angle_by_index[4] = { 0, 2, 6, 12}; +static const int angle_by_index[4] = { 0, 2, 6, 12}; /* Lookup tables for luma and chroma - used by ulti_convert_yuv() */ -static uint8_t ulti_lumas[64] = +static const uint8_t ulti_lumas[64] = { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28, 0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44, 0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60, @@ -72,7 +72,7 @@ static uint8_t ulti_lumas[64] = 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF, 0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB}; -static uint8_t ulti_chromas[16] = +static const uint8_t ulti_chromas[16] = { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D, 0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0}; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/utils.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/utils.c @@ -193,7 +193,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ return -1; if(s->internal_buffer==NULL){ - s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer)); + s->internal_buffer= av_mallocz((INTERNAL_BUFFER_SIZE+1)*sizeof(InternalBuffer)); } #if 0 s->internal_buffer= av_fast_realloc( @@ -204,7 +204,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ #endif buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; - picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE-1]).last_pic_num; //FIXME ugly hack + picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack (*picture_number)++; if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ @@ -444,13 +444,13 @@ static const AVOption options[]={ {"frame_number", NULL, OFFSET(frame_number), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, {"real_pict_num", NULL, OFFSET(real_pict_num), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, {"delay", NULL, OFFSET(delay), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), FF_OPT_TYPE_FLOAT, 0.5, FLT_MIN, FLT_MAX, V|E}, -{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), FF_OPT_TYPE_FLOAT, 0.5, FLT_MIN, FLT_MAX, V|E}, +{"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), FF_OPT_TYPE_FLOAT, 0.5, -FLT_MAX, FLT_MAX, V|E}, +{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), FF_OPT_TYPE_FLOAT, 0.5, 0, FLT_MAX, V|E}, {"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), FF_OPT_TYPE_INT, 2, 1, 51, V|E}, {"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), FF_OPT_TYPE_INT, 31, 1, 51, V|E}, {"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), FF_OPT_TYPE_INT, 3, INT_MIN, INT_MAX, V|E}, {"bf", "use 'frames' B frames", OFFSET(max_b_frames), FF_OPT_TYPE_INT, DEFAULT, 0, FF_MAX_B_FRAMES, V|E}, -{"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, 1.25, FLT_MIN, FLT_MAX, V|E}, +{"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, 1.25, -FLT_MAX, FLT_MAX, V|E}, {"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX, V|E}, {"hurry_up", NULL, OFFSET(hurry_up), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, @@ -486,13 +486,13 @@ static const AVOption options[]={ {"ms", "workaround various bugs in microsofts broken decoders", 0, FF_OPT_TYPE_CONST, FF_BUG_MS, INT_MIN, INT_MAX, V|D, "bug"}, {"lelim", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)", OFFSET(luma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"celim", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)", OFFSET(chroma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|V|D, "strict"}, -{"very", "strictly conform to a older more strict version of the spec or reference software", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_VERY_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, -{"strict", "strictly conform to all the things in the spec no matter what consequences", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, -{"normal", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_NORMAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"inofficial", "allow inofficial extensions", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"experimental", "allow non standardized experimental things", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"b_qoffset", "qp offset between P and B frames", OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, 1.25, FLT_MIN, FLT_MAX, V|E}, +{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"very", "strictly conform to a older more strict version of the spec or reference software", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_VERY_STRICT, INT_MIN, INT_MAX, V|D|E, "strict"}, +{"strict", "strictly conform to all the things in the spec no matter what consequences", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_STRICT, INT_MIN, INT_MAX, V|D|E, "strict"}, +{"normal", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_NORMAL, INT_MIN, INT_MAX, V|D|E, "strict"}, +{"inofficial", "allow inofficial extensions", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|D|E, "strict"}, +{"experimental", "allow non standardized experimental things", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|D|E, "strict"}, +{"b_qoffset", "qp offset between P and B frames", OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, 1.25, -FLT_MAX, FLT_MAX, V|E}, {"er", "set error resilience strategy", OFFSET(error_resilience), FF_OPT_TYPE_INT, FF_ER_CAREFUL, INT_MIN, INT_MAX, A|V|D, "er"}, {"careful", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, {"compliant", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_COMPLIANT, INT_MIN, INT_MAX, V|D, "er"}, @@ -512,7 +512,7 @@ static const AVOption options[]={ {"maxrate", "set max video bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"minrate", "set min video bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|V|E}, -{"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, 1.0, FLT_MIN, FLT_MAX, V|E}, +{"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, 1.0, -FLT_MAX, FLT_MAX, V|E}, {"i_qfactor", "qp factor between P and I frames", OFFSET(i_quant_factor), FF_OPT_TYPE_FLOAT, -0.8, -FLT_MAX, FLT_MAX, V|E}, {"i_qoffset", "qp offset between P and I frames", OFFSET(i_quant_offset), FF_OPT_TYPE_FLOAT, 0.0, -FLT_MAX, FLT_MAX, V|E}, {"rc_init_cplx", "initial complexity for 1-pass encoding", OFFSET(rc_initial_cplx), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, @@ -543,6 +543,7 @@ static const AVOption options[]={ {"sh4", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SH4, INT_MIN, INT_MAX, V|E|D, "idct"}, {"simplearm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARM, INT_MIN, INT_MAX, V|E|D, "idct"}, {"simplearmv5te", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARMV5TE, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARMV6, INT_MIN, INT_MAX, V|E|D, "idct"}, {"h264", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_H264, INT_MIN, INT_MAX, V|E|D, "idct"}, {"vp3", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_VP3, INT_MIN, INT_MAX, V|E|D, "idct"}, {"ipp", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_IPP, INT_MIN, INT_MAX, V|E|D, "idct"}, @@ -738,7 +739,7 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType codec_type) flags= AV_OPT_FLAG_SUBTITLE_PARAM; av_opt_set_defaults2(s, flags, flags); - s->rc_eq= "tex^qComp"; + s->rc_eq= av_strdup("tex^qComp"); s->time_base= (AVRational){0,1}; s->get_buffer= avcodec_default_get_buffer; s->release_buffer= avcodec_default_release_buffer; @@ -956,6 +957,7 @@ int avcodec_close(AVCodecContext *avctx) avctx->codec->close(avctx); avcodec_default_free_buffers(avctx); av_freep(&avctx->priv_data); + av_freep(&avctx->rc_eq); avctx->codec = NULL; return 0; } @@ -1182,10 +1184,12 @@ unsigned avcodec_version( void ) return LIBAVCODEC_VERSION_INT; } +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) unsigned avcodec_build( void ) { return LIBAVCODEC_BUILD; } +#endif void avcodec_init(void) { @@ -1352,7 +1356,7 @@ typedef struct { int rate_num, rate_den; } VideoFrameRateAbbr; -static VideoFrameSizeAbbr video_frame_size_abbrs[] = { +static const VideoFrameSizeAbbr video_frame_size_abbrs[] = { { "ntsc", 720, 480 }, { "pal", 720, 576 }, { "qntsc", 352, 240 }, /* VCD compliant NTSC */ @@ -1391,7 +1395,7 @@ static VideoFrameSizeAbbr video_frame_size_abbrs[] = { { "hd1080", 1920,1080 }, }; -static VideoFrameRateAbbr video_frame_rate_abbrs[]= { +static const VideoFrameRateAbbr video_frame_rate_abbrs[]= { { "ntsc", 30000, 1001 }, { "pal", 25, 1 }, { "qntsc", 30000, 1001 }, /* VCD compliant NTSC */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vc1.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vc1.c @@ -783,8 +783,8 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb) } else { - v->zz_8x4 = ff_vc1_simple_progressive_8x4_zz; - v->zz_4x8 = ff_vc1_simple_progressive_4x8_zz; + v->zz_8x4 = wmv2_scantableA; + v->zz_4x8 = wmv2_scantableB; v->res_sm = get_bits(gb, 2); //reserved if (v->res_sm) { @@ -2398,11 +2398,11 @@ static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded if(v->s.ac_pred) { if(!dc_pred_dir) - zz_table = ff_vc1_horizontal_zz; + zz_table = wmv1_scantable[2]; else - zz_table = ff_vc1_vertical_zz; + zz_table = wmv1_scantable[3]; } else - zz_table = ff_vc1_normal_zz; + zz_table = wmv1_scantable[1]; ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val2 = ac_val; @@ -2581,11 +2581,11 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c if(v->s.ac_pred) { if(!dc_pred_dir) - zz_table = ff_vc1_horizontal_zz; + zz_table = wmv1_scantable[2]; else - zz_table = ff_vc1_vertical_zz; + zz_table = wmv1_scantable[3]; } else - zz_table = ff_vc1_normal_zz; + zz_table = wmv1_scantable[1]; while (!last) { vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); @@ -2786,7 +2786,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c const int8_t *zz_table; int k; - zz_table = ff_vc1_simple_progressive_8x8_zz; + zz_table = wmv1_scantable[0]; while (!last) { vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); @@ -2928,7 +2928,7 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 63) break; - idx = ff_vc1_simple_progressive_8x8_zz[i++]; + idx = wmv1_scantable[0][i++]; block[idx] = value * scale; if(!v->pquantizer) block[idx] += (block[idx] < 0) ? -mquant : mquant; @@ -4005,6 +4005,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, divider = find_next_marker(buf, buf + buf_size); if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); + av_free(buf2); return -1; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vc1data.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vc1data.c @@ -562,75 +562,6 @@ const uint8_t ff_vc1_mv_diff_bits[4][73] = { /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ -/* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */ -const int8_t ff_vc1_normal_zz[64] = { - 0, 8, 1, 2, 9, 16, 24, 17, - 10, 3, 4, 11, 18, 25, 32, 40, - 33, 48, 26, 19, 12, 5, 6, 13, - 20, 27, 34, 41, 56, 49, 57, 42, - 35, 28, 21, 14, 7, 15, 22, 29, - 36, 43, 50, 58, 51, 59, 44, 37, - 30, 23, 31, 38, 45, 52, 60, 53, - 61, 46, 39, 47, 54, 62, 55, 63 -}; - -const int8_t ff_vc1_horizontal_zz [64] = /* Table 227 */ -{ - 0, 1, 8, 2, 3, 9, 16, 24, - 17, 10, 4, 5, 11, 18, 25, 32, - 40, 48, 33, 26, 19, 12, 6, 7, - 13, 20, 27, 34, 41, 56, 49, 57, - 42, 35, 28, 21, 14, 15, 22, 29, - 36, 43, 50, 58, 51, 44, 37, 30, - 23, 31, 38, 45, 52, 59, 60, 53, - 46, 39, 47, 54, 61, 62, 55, 63 -}; - -const int8_t ff_vc1_vertical_zz [64] = /* Table 228 */ -{ - 0, 8, 16, 1, 24, 32, 40, 9, - 2, 3, 10, 17, 25, 48, 56, 41, - 33, 26, 18, 11, 4, 5, 12, 19, - 27, 34, 49, 57, 50, 42, 35, 28, - 20, 13, 6, 7, 14, 21, 29, 36, - 43, 51, 58, 59, 52, 44, 37, 30, - 22, 15, 23, 31, 38, 45, 60, 53, - 46, 39, 47, 54, 61, 62, 55, 63 -}; - -const int8_t ff_vc1_simple_progressive_8x8_zz [64] = -/* Table 229 */ -{ - 0, 8, 1, 2, 9, 16, 24, 17, - 10, 3, 4, 11, 18, 25, 32, 40, - 48, 56, 41, 33, 26, 19, 12, 5, - 6, 13, 20, 27, 34, 49, 57, 58, - 50, 42, 35, 28, 21, 14, 7, 15, - 22, 29, 36, 43, 51, 59, 60, 52, - 44, 37, 30, 23, 31, 38, 45, 53, - 61, 62, 54, 46, 39, 47, 55, 63 -}; - -const int8_t ff_vc1_simple_progressive_8x4_zz [32] = /* Table 230 */ -{ - 0, 1, 2, 8, 3, 9, 10, 16, - 4, 11, 17, 24, 18, 12, 5, 19, - 25, 13, 20, 26, 27, 6, 21, 28, - 14, 22, 29, 7, 30, 15, 23, 31 -}; - -const int8_t ff_vc1_simple_progressive_4x8_zz [32] = /* Table 231 */ -{ - 0, 8, 1, 16, - 9, 24, 17, 2, - 32, 10, 25, 40, - 18, 48, 33, 26, - 56, 41, 34, 3, - 49, 57, 11, 42, - 19, 50, 27, 58, - 35, 43, 51, 59 -}; - /* Table 232 */ const int8_t ff_vc1_simple_progressive_4x4_zz [16] = { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vc1data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vc1data.h @@ -143,12 +143,6 @@ extern const uint8_t ff_vc1_mv_diff_bits[4][73]; /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ /* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */ -extern const int8_t ff_vc1_normal_zz[64]; -extern const int8_t ff_vc1_horizontal_zz [64]; -extern const int8_t ff_vc1_vertical_zz [64]; -extern const int8_t ff_vc1_simple_progressive_8x8_zz [64]; -extern const int8_t ff_vc1_simple_progressive_8x4_zz [32]; -extern const int8_t ff_vc1_simple_progressive_4x8_zz [32]; extern const int8_t ff_vc1_simple_progressive_4x4_zz [16]; extern const int8_t ff_vc1_adv_progressive_8x4_zz [32]; extern const int8_t ff_vc1_adv_progressive_4x8_zz [32]; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vmdav.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vmdav.c @@ -422,7 +422,7 @@ typedef struct VmdAudioContext { int predictors[2]; } VmdAudioContext; -static uint16_t vmdaudio_table[128] = { +static const uint16_t vmdaudio_table[128] = { 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vorbis.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vorbis.h @@ -24,7 +24,7 @@ #include "avcodec.h" extern const float ff_vorbis_floor1_inverse_db_table[256]; -extern const float * ff_vorbis_vwin[8]; +extern const float * const ff_vorbis_vwin[8]; typedef struct { uint_fast16_t x; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vorbis_data.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vorbis_data.c @@ -2151,5 +2151,5 @@ const float ff_vorbis_floor1_inverse_db_table[256]={ 0.82788260F, 0.88168307F, 0.9389798F, 1.F, }; -const float * ff_vorbis_vwin[8] = { vwin64, vwin128, vwin256, vwin512, vwin1024, vwin2048, vwin4096, vwin8192 }; +const float * const ff_vorbis_vwin[8] = { vwin64, vwin128, vwin256, vwin512, vwin1024, vwin2048, vwin4096, vwin8192 }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vorbis_dec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vorbis_dec.c @@ -149,13 +149,10 @@ typedef struct vorbis_context_s { uint_fast8_t mode_count; vorbis_mode *modes; uint_fast8_t mode_number; // mode number for the current packet + uint_fast8_t previous_window; float *channel_residues; float *channel_floors; float *saved; - uint_fast16_t saved_start; - float *ret; - float *buf; - float *buf_tmp; uint_fast32_t add_bias; // for float->int conversion uint_fast32_t exp_bias; } vorbis_context; @@ -181,9 +178,6 @@ static void vorbis_free(vorbis_context *vc) { av_freep(&vc->channel_residues); av_freep(&vc->channel_floors); av_freep(&vc->saved); - av_freep(&vc->ret); - av_freep(&vc->buf); - av_freep(&vc->buf_tmp); av_freep(&vc->residues); av_freep(&vc->modes); @@ -899,11 +893,8 @@ static int vorbis_parse_id_hdr(vorbis_context *vc){ vc->channel_residues= av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); vc->channel_floors = av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->saved = av_mallocz((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->ret = av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->buf = av_malloc( vc->blocksize[1] * sizeof(float)); - vc->buf_tmp = av_malloc( vc->blocksize[1] * sizeof(float)); - vc->saved_start=0; + vc->saved = av_mallocz((vc->blocksize[1]/4)*vc->audio_channels * sizeof(float)); + vc->previous_window=0; ff_mdct_init(&vc->mdct[0], bl0, 1); ff_mdct_init(&vc->mdct[1], bl1, 1); @@ -979,6 +970,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) { avccontext->channels = vc->audio_channels; avccontext->sample_rate = vc->audio_samplerate; + avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1])>>2; return 0 ; } @@ -1329,6 +1321,14 @@ static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fa vec[voffs+k ]+=codebook.codevectors[coffs ]; // FPMATH vec[voffs+k+vlen]+=codebook.codevectors[coffs+1]; // FPMATH } + } else if(dim==4) { + for(k=0;k<step;++k, voffs+=2) { + coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 4; + vec[voffs ]+=codebook.codevectors[coffs ]; // FPMATH + vec[voffs+1 ]+=codebook.codevectors[coffs+2]; // FPMATH + vec[voffs+vlen ]+=codebook.codevectors[coffs+1]; // FPMATH + vec[voffs+vlen+1]+=codebook.codevectors[coffs+3]; // FPMATH + } } else for(k=0;k<step;++k) { coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; @@ -1393,15 +1393,28 @@ void vorbis_inverse_coupling(float *mag, float *ang, int blocksize) } } +static void copy_normalize(float *dst, float *src, int len, int exp_bias, float add_bias) +{ + int i; + if(exp_bias) { + for(i=0; i<len; i++) + ((uint32_t*)dst)[i] = ((uint32_t*)src)[i] + exp_bias; // dst[k]=src[i]*(1<<bias) + } else { + for(i=0; i<len; i++) + dst[i] = src[i] + add_bias; + } +} + // Decode the audio packet using the functions above static int vorbis_parse_audio_packet(vorbis_context *vc) { GetBitContext *gb=&vc->gb; - uint_fast8_t previous_window=0,next_window=0; + uint_fast8_t previous_window=vc->previous_window; uint_fast8_t mode_number; + uint_fast8_t blockflag; uint_fast16_t blocksize; - int_fast32_t i,j; + int_fast32_t i,j,dir; uint_fast8_t no_residue[vc->audio_channels]; uint_fast8_t do_not_decode[vc->audio_channels]; vorbis_mapping *mapping; @@ -1410,7 +1423,6 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) { uint_fast8_t res_chan[vc->audio_channels]; uint_fast8_t res_num=0; int_fast16_t retlen=0; - uint_fast16_t saved_start=0; float fadd_bias = vc->add_bias; if (get_bits1(gb)) { @@ -1428,12 +1440,12 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) { AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag); - if (vc->modes[mode_number].blockflag) { - previous_window=get_bits1(gb); - next_window=get_bits1(gb); + blockflag=vc->modes[mode_number].blockflag; + blocksize=vc->blocksize[blockflag]; + if (blockflag) { + skip_bits(gb, 2); // previous_window, next_window } - blocksize=vc->blocksize[vc->modes[mode_number].blockflag]; memset(ch_res_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ? memset(ch_floor_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ? @@ -1503,76 +1515,34 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) { // MDCT, overlap/add, save data for next overlapping FPMATH - for(j=0;j<vc->audio_channels;++j) { - uint_fast8_t step=vc->audio_channels; - uint_fast16_t k; - float *saved=vc->saved+j*vc->blocksize[1]/2; - float *ret=vc->ret; - const float *lwin=vc->win[1]; - const float *swin=vc->win[0]; - float *buf=vc->buf; - float *buf_tmp=vc->buf_tmp; - - ch_floor_ptr=vc->channel_floors+j*blocksize/2; - - saved_start=vc->saved_start; - - vc->mdct[0].fft.imdct_calc(&vc->mdct[vc->modes[mode_number].blockflag], buf, ch_floor_ptr, buf_tmp); - - //FIXME process channels together, to allow faster simd vector_fmul_add_add? - if (vc->modes[mode_number].blockflag) { - // -- overlap/add - if (previous_window) { - vc->dsp.vector_fmul_add_add(ret+j, buf, lwin, saved, vc->add_bias, vc->blocksize[1]/2, step); - retlen=vc->blocksize[1]/2; - } else { - int len = (vc->blocksize[1]-vc->blocksize[0])/4; - buf += len; - vc->dsp.vector_fmul_add_add(ret+j, buf, swin, saved, vc->add_bias, vc->blocksize[0]/2, step); - k = vc->blocksize[0]/2*step + j; - buf += vc->blocksize[0]/2; - if(vc->exp_bias){ - for(i=0; i<len; i++, k+=step) - ((uint32_t*)ret)[k] = ((uint32_t*)buf)[i] + vc->exp_bias; // ret[k]=buf[i]*(1<<bias) - } else { - for(i=0; i<len; i++, k+=step) - ret[k] = buf[i] + fadd_bias; - } - buf=vc->buf; - retlen=vc->blocksize[0]/2+len; - } - // -- save - if (next_window) { - buf += vc->blocksize[1]/2; - vc->dsp.vector_fmul_reverse(saved, buf, lwin, vc->blocksize[1]/2); - saved_start=0; - } else { - saved_start=(vc->blocksize[1]-vc->blocksize[0])/4; - buf += vc->blocksize[1]/2; - for(i=0; i<saved_start; i++) - ((uint32_t*)saved)[i] = ((uint32_t*)buf)[i] + vc->exp_bias; - vc->dsp.vector_fmul_reverse(saved+saved_start, buf+saved_start, swin, vc->blocksize[0]/2); - } + retlen = (blocksize + vc->blocksize[previous_window])/4; + dir = retlen <= blocksize/2; // pick an order so that ret[] can reuse residues[] without stepping on any data we need + for(j=dir?0:vc->audio_channels-1; (unsigned)j<vc->audio_channels; j+=dir*2-1) { + uint_fast16_t bs0=vc->blocksize[0]; + uint_fast16_t bs1=vc->blocksize[1]; + float *residue=vc->channel_residues+res_chan[j]*blocksize/2; + float *floor=vc->channel_floors+j*blocksize/2; + float *saved=vc->saved+j*bs1/4; + float *ret=vc->channel_residues+j*retlen; + float *buf=floor; + const float *win=vc->win[blockflag&previous_window]; + + vc->mdct[0].fft.imdct_half(&vc->mdct[blockflag], buf, floor, residue); + + if(blockflag == previous_window) { + vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, blocksize/4); + } else if(blockflag > previous_window) { + vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, bs0/4); + copy_normalize(ret+bs0/2, buf+bs0/4, (bs1-bs0)/4, vc->exp_bias, fadd_bias); } else { - // --overlap/add - if(vc->add_bias) { - for(k=j, i=0;i<saved_start;++i, k+=step) - ret[k] = saved[i] + fadd_bias; - } else { - for(k=j, i=0;i<saved_start;++i, k+=step) - ret[k] = saved[i]; - } - vc->dsp.vector_fmul_add_add(ret+k, buf, swin, saved+saved_start, vc->add_bias, vc->blocksize[0]/2, step); - retlen=saved_start+vc->blocksize[0]/2; - // -- save - buf += vc->blocksize[0]/2; - vc->dsp.vector_fmul_reverse(saved, buf, swin, vc->blocksize[0]/2); - saved_start=0; + copy_normalize(ret, saved, (bs1-bs0)/4, vc->exp_bias, fadd_bias); + vc->dsp.vector_fmul_window(ret+(bs1-bs0)/4, saved+(bs1-bs0)/4, buf, win, fadd_bias, bs0/4); } + memcpy(saved, buf+blocksize/4, blocksize/4*sizeof(float)); } - vc->saved_start=saved_start; - return retlen*vc->audio_channels; + vc->previous_window = blockflag; + return retlen; } // Return the decoded audio packet through the standard api @@ -1583,6 +1553,8 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, { vorbis_context *vc = avccontext->priv_data ; GetBitContext *gb = &(vc->gb); + const float *channel_ptrs[vc->audio_channels]; + int i; int_fast16_t len; @@ -1609,8 +1581,10 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len); - vc->dsp.float_to_int16(data, vc->ret, len); - *data_size=len*2; + for(i=0; i<vc->audio_channels; i++) + channel_ptrs[i] = vc->channel_residues+i*len; + vc->dsp.float_to_int16_interleave(data, channel_ptrs, len, vc->audio_channels); + *data_size=len*2*vc->audio_channels; return buf_size ; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3.c @@ -172,11 +172,8 @@ typedef struct Vp3Fragment { #define MODE_COPY 8 /* There are 6 preset schemes, plus a free-form scheme */ -static int ModeAlphabet[7][CODING_MODE_COUNT] = +static const int ModeAlphabet[6][CODING_MODE_COUNT] = { - /* this is the custom scheme */ - { 0, 0, 0, 0, 0, 0, 0, 0 }, - /* scheme 1: Last motion vector dominates */ { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, @@ -877,6 +874,7 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) int current_macroblock; int current_fragment; int coding_mode; + int custom_mode_alphabet[CODING_MODE_COUNT]; debug_vp3(" vp3: unpacking encoding modes\n"); @@ -896,12 +894,17 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) if (scheme == 0) { debug_modes(" custom mode alphabet ahead:\n"); for (i = 0; i < 8; i++) - ModeAlphabet[scheme][get_bits(gb, 3)] = i; + custom_mode_alphabet[get_bits(gb, 3)] = i; } - for (i = 0; i < 8; i++) - debug_modes(" mode[%d][%d] = %d\n", scheme, i, - ModeAlphabet[scheme][i]); + for (i = 0; i < 8; i++) { + if(scheme) + debug_modes(" mode[%d][%d] = %d\n", scheme, i, + ModeAlphabet[scheme-1][i]); + else + debug_modes(" mode[0][%d] = %d\n", i, + custom_mode_alphabet[i]); + } /* iterate through all of the macroblocks that contain 1 or more * coded fragments */ @@ -921,8 +924,11 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) /* mode 7 means get 3 bits for each coding mode */ if (scheme == 7) coding_mode = get_bits(gb, 3); + else if(scheme == 0) + coding_mode = custom_mode_alphabet + [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; else - coding_mode = ModeAlphabet[scheme] + coding_mode = ModeAlphabet[scheme-1] [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; s->macroblock_coding[current_macroblock] = coding_mode; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3_parser.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3_parser.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "parser.h" + +static int parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + if(avctx->codec_id == CODEC_ID_THEORA) + s->pict_type= (buf[0]&0x40) ? FF_P_TYPE : FF_I_TYPE; + else + s->pict_type= (buf[0]&0x80) ? FF_P_TYPE : FF_I_TYPE; + + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +AVCodecParser vp3_parser = { + { CODEC_ID_THEORA, CODEC_ID_VP3, + CODEC_ID_VP6, CODEC_ID_VP6F, CODEC_ID_VP6A }, + 0, + NULL, + parse, +}; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3data.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3data.h @@ -405,7 +405,7 @@ static const int16_t coeff_table_token_22[1024] = { -573, -574, -575, -576, -577, -578, -579, -580 }; -static const int16_t *coeff_tables[32] = { +static const int16_t *const coeff_tables[32] = { NULL, NULL, NULL, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3dsp.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp3dsp.c @@ -190,7 +190,7 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int dst[4*stride]= dst[5*stride]= dst[6*stride]= - dst[7*stride]= 128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20); + dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)]; }else{ if(ip[0*8]){ int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp6.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/vp6.c @@ -202,10 +202,11 @@ static void vp6_parse_vector_models(vp56_context_t *s) model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7); } +/* nodes must ascend by count, but with descending symbol order */ static int vp6_huff_cmp(const void *va, const void *vb) { const Node *a = va, *b = vb; - return a->count >= b->count; + return (a->count - b->count)*16 + (b->sym - a->sym); } static void vp6_build_huff_tree(vp56_context_t *s, uint8_t coeff_model[], diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/wmadec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/wmadec.c @@ -401,13 +401,14 @@ static int wma_decode_block(WMACodecContext *s) s->channel_coded[ch] = a; v |= a; } + + bsize = s->frame_len_bits - s->block_len_bits; + /* if no channel coded, no need to go further */ /* XXX: fix potential framing problems */ if (!v) goto next; - bsize = s->frame_len_bits - s->block_len_bits; - /* read total gain and extract corresponding number of bits for coef escape coding */ total_gain = 1; @@ -679,27 +680,29 @@ static int wma_decode_block(WMACodecContext *s) } } +next: for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - int n4, index, n; + int n4, index, n; - n = s->block_len; - n4 = s->block_len / 2; + n = s->block_len; + n4 = s->block_len / 2; + if(s->channel_coded[ch]){ s->mdct_ctx[bsize].fft.imdct_calc(&s->mdct_ctx[bsize], - s->output, s->coefs[ch], s->mdct_tmp); - - /* multiply by the window and add in the frame */ - index = (s->frame_len / 2) + s->block_pos - n4; - wma_window(s, &s->frame_out[ch][index]); - - /* specific fast case for ms-stereo : add to second - channel if it is not coded */ - if (s->ms_stereo && !s->channel_coded[1]) { - wma_window(s, &s->frame_out[1][index]); - } + s->output, s->coefs[ch], s->mdct_tmp); + }else + memset(s->output, 0, sizeof(s->output)); + + /* multiply by the window and add in the frame */ + index = (s->frame_len / 2) + s->block_pos - n4; + wma_window(s, &s->frame_out[ch][index]); + + /* specific fast case for ms-stereo : add to second + channel if it is not coded */ + if (s->ms_stereo && !s->channel_coded[1]) { + wma_window(s, &s->frame_out[1][index]); } } - next: + /* update block number */ s->block_num++; s->block_pos += s->block_len; @@ -781,6 +784,11 @@ static int wma_decode_superframe(AVCodecContext *avctx, skip_bits(&s->gb, 4); /* super frame index */ nb_frames = get_bits(&s->gb, 4) - 1; + if((nb_frames+1) * s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ + av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); + goto fail; + } + bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); if (s->last_superframe_len > 0) { @@ -836,6 +844,10 @@ static int wma_decode_superframe(AVCodecContext *avctx, s->last_superframe_len = len; memcpy(s->last_superframe, buf + pos, len); } else { + if(s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ + av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); + goto fail; + } /* single frame decode */ if (wma_decode_frame(s, samples) < 0) goto fail; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/wnv1.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavcodec/wnv1.c @@ -36,7 +36,7 @@ typedef struct WNV1Context{ GetBitContext gb; } WNV1Context; -static uint16_t code_tab[16][2]={ +static const uint16_t code_tab[16][2]={ {0x1FD,9}, {0xFD,8}, {0x7D,7}, {0x3D,6}, {0x1D,5}, {0x0D,4}, {0x005,3}, {0x000,1}, {0x004,3}, {0x0C,4}, {0x1C,5}, {0x3C,6}, {0x7C,7}, {0xFC,8}, {0x1FC,9}, {0xFF,8} diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavdevice/audio.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavdevice/audio.c @@ -47,7 +47,7 @@ typedef struct { int channels; int frame_size; /* in bytes ! */ int codec_id; - int flip_left : 1; + unsigned int flip_left : 1; uint8_t buffer[AUDIO_BLOCK_SIZE]; int buffer_ptr; } AudioData; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavdevice/v4l.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavdevice/v4l.c @@ -258,7 +258,6 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) fail: if (video_fd >= 0) close(video_fd); - av_free(st); return AVERROR(EIO); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavdevice/v4l2.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavdevice/v4l2.c @@ -526,8 +526,6 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) capabilities = 0; s->fd = device_open(s1, &capabilities); if (s->fd < 0) { - av_free(st); - return AVERROR(EIO); } av_log(s1, AV_LOG_INFO, "[%d]Capabilities: %x\n", s->fd, capabilities); @@ -553,7 +551,6 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) if (desired_format == 0) { av_log(s1, AV_LOG_ERROR, "Cannot find a proper format.\n"); close(s->fd); - av_free(st); return AVERROR(EIO); } @@ -576,7 +573,6 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) } if (res < 0) { close(s->fd); - av_free(st); return AVERROR(EIO); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/Makefile b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/Makefile @@ -33,8 +33,11 @@ OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o OBJS-$(CONFIG_CRC_MUXER) += crcenc.o OBJS-$(CONFIG_DAUD_DEMUXER) += daud.o +OBJS-$(CONFIG_DIRAC_DEMUXER) += raw.o +OBJS-$(CONFIG_DIRAC_MUXER) += raw.o OBJS-$(CONFIG_DSICIN_DEMUXER) += dsicin.o OBJS-$(CONFIG_DTS_DEMUXER) += raw.o +OBJS-$(CONFIG_DTS_MUXER) += raw.o OBJS-$(CONFIG_DV_DEMUXER) += dv.o OBJS-$(CONFIG_DV_MUXER) += dvenc.o OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o riff.o @@ -50,7 +53,7 @@ OBJS-$(CONFIG_FLV_MUXER) += flvenc.o avc.o OBJS-$(CONFIG_FOURXM_DEMUXER) += 4xm.o OBJS-$(CONFIG_FRAMECRC_MUXER) += framecrcenc.o OBJS-$(CONFIG_GIF_MUXER) += gif.o -OBJS-$(CONFIG_GIF_DEMUXER) += gifdec.o +OBJS-$(CONFIG_GSM_DEMUXER) += raw.o OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o OBJS-$(CONFIG_H261_DEMUXER) += raw.o @@ -103,6 +106,7 @@ OBJS-$(CONFIG_MPEGVIDEO_DEMUXER) += raw.o OBJS-$(CONFIG_MPJPEG_MUXER) += mpjpeg.o OBJS-$(CONFIG_MSNWC_TCP_DEMUXER) += msnwc_tcp.o OBJS-$(CONFIG_MTV_DEMUXER) += mtv.o +OBJS-$(CONFIG_MVI_DEMUXER) += mvi.o OBJS-$(CONFIG_MXF_DEMUXER) += mxf.o OBJS-$(CONFIG_NSV_DEMUXER) += nsvdec.o OBJS-$(CONFIG_NULL_MUXER) += raw.o @@ -117,7 +121,7 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ oggparsevorbis.o \ riff.o OBJS-$(CONFIG_OGG_MUXER) += oggenc.o -OBJS-$(CONFIG_OMA_DEMUXER) += oma.o +OBJS-$(CONFIG_OMA_DEMUXER) += oma.o raw.o OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += raw.o OBJS-$(CONFIG_PCM_ALAW_MUXER) += raw.o OBJS-$(CONFIG_PCM_MULAW_DEMUXER) += raw.o diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/aiff.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/aiff.c @@ -25,26 +25,26 @@ #include "riff.h" static const AVCodecTag codec_aiff_tags[] = { - { CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_S8, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, - { CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, - { CODEC_ID_MACE3, MKTAG('M','A','C','3') }, - { CODEC_ID_MACE6, MKTAG('M','A','C','6') }, - { CODEC_ID_GSM, MKTAG('G','S','M',' ') }, - { CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') }, - { CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, + { CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') }, + { CODEC_ID_PCM_S8, MKTAG('N','O','N','E') }, + { CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') }, + { CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') }, + { CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, + { CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, + { CODEC_ID_MACE3, MKTAG('M','A','C','3') }, + { CODEC_ID_MACE6, MKTAG('M','A','C','6') }, + { CODEC_ID_GSM, MKTAG('G','S','M',' ') }, + { CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') }, + { CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, { CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, - { CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, + { CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, { 0, 0 }, }; #define AIFF 0 #define AIFF_C_VERSION1 0xA2805140 -static int aiff_codec_get_id (int bps) +static int aiff_codec_get_id(int bps) { if (bps <= 8) return CODEC_ID_PCM_S8; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/allformats.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/allformats.c @@ -82,7 +82,7 @@ void av_register_all(void) REGISTER_MUXDEMUX (FLV, flv); REGISTER_DEMUXER (FOURXM, fourxm); REGISTER_MUXER (FRAMECRC, framecrc); - REGISTER_MUXDEMUX (GIF, gif); + REGISTER_MUXER (GIF, gif); REGISTER_DEMUXER (GSM, gsm); REGISTER_MUXDEMUX (GXF, gxf); REGISTER_MUXDEMUX (H261, h261); @@ -123,6 +123,7 @@ void av_register_all(void) REGISTER_MUXER (MPJPEG, mpjpeg); REGISTER_DEMUXER (MSNWC_TCP, msnwc_tcp); REGISTER_DEMUXER (MTV, mtv); + REGISTER_DEMUXER (MVI, mvi); REGISTER_DEMUXER (MXF, mxf); REGISTER_DEMUXER (NSV, nsv); REGISTER_MUXER (NULL, null); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/asf.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/asf.c @@ -49,7 +49,7 @@ static const GUID stream_bitrate_guid = { /* (http://get.to/sdp) */ #ifdef DEBUG #define PRINT_IF_GUID(g,cmp) \ if (!memcmp(g, &cmp, sizeof(GUID))) \ - printf("(GUID: %s) ", #cmp) + dprintf(NULL, "(GUID: %s) ", #cmp) static void print_guid(const GUID *g) { @@ -77,12 +77,14 @@ static void print_guid(const GUID *g) else PRINT_IF_GUID(g, metadata_header); else PRINT_IF_GUID(g, stream_bitrate_guid); else - printf("(GUID: unknown) "); + dprintf(NULL, "(GUID: unknown) "); for(i=0;i<16;i++) - printf(" 0x%02x,", (*g)[i]); - printf("}\n"); + dprintf(NULL, " 0x%02x,", (*g)[i]); + dprintf(NULL, "}\n"); } #undef PRINT_IF_GUID +#else +#define print_guid(g) #endif static void get_guid(ByteIOContext *s, GUID *g) @@ -156,7 +158,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_guid(pb, &g); if (memcmp(&g, &asf_header, sizeof(GUID))) - goto fail; + return -1; get_le64(pb); get_le32(pb); get_byte(pb); @@ -165,11 +167,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) for(;;) { get_guid(pb, &g); gsize = get_le64(pb); -#ifdef DEBUG - printf("%08"PRIx64": ", url_ftell(pb) - 24); + dprintf(s, "%08"PRIx64": ", url_ftell(pb) - 24); print_guid(&g); - printf(" size=0x%"PRIx64"\n", gsize); -#endif + dprintf(s, " size=0x%"PRIx64"\n", gsize); if (!memcmp(&g, &data_header, sizeof(GUID))) { asf->data_object_offset = url_ftell(pb); // if not streaming, gsize is not unlimited (how?), and there is enough space in the file.. @@ -181,7 +181,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) break; } if (gsize < 24) - goto fail; + return -1; if (!memcmp(&g, &file_header, sizeof(GUID))) { get_guid(pb, &asf->hdr.guid); asf->hdr.file_size = get_le64(pb); @@ -207,11 +207,11 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) st = av_new_stream(s, 0); if (!st) - goto fail; + return AVERROR(ENOMEM); av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ asf_st = av_mallocz(sizeof(ASFStream)); if (!asf_st) - goto fail; + return AVERROR(ENOMEM); st->priv_data = asf_st; start_time = asf->hdr.preroll; @@ -227,12 +227,12 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) } else if (!memcmp(&g, &video_stream, sizeof(GUID))) { type = CODEC_TYPE_VIDEO; } else if (!memcmp(&g, &command_stream, sizeof(GUID))) { - type = CODEC_TYPE_UNKNOWN; + type = CODEC_TYPE_DATA; } else if (!memcmp(&g, &ext_stream_embed_stream_header, sizeof(GUID))) { test_for_ext_stream_audio = 1; type = CODEC_TYPE_UNKNOWN; } else { - goto fail; + return -1; } get_guid(pb, &g); total_size = get_le64(pb); @@ -264,7 +264,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (is_dvr_ms_audio) { // codec_id and codec_tag are unreliable in dvr_ms // files. Set them later by probing stream. - st->codec->codec_id = CODEC_ID_NONE; + st->codec->codec_id = CODEC_ID_PROBE; st->codec->codec_tag = 0; } st->need_parsing = AVSTREAM_PARSE_FULL; @@ -513,7 +513,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) } #endif } else if (url_feof(pb)) { - goto fail; + return -1; } else { url_fseek(pb, gsize - 24, SEEK_CUR); } @@ -523,7 +523,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_byte(pb); get_byte(pb); if (url_feof(pb)) - goto fail; + return -1; asf->data_offset = url_ftell(pb); asf->packet_size_left = 0; @@ -543,17 +543,6 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) } return 0; - - fail: - for(i=0;i<s->nb_streams;i++) { - AVStream *st = s->streams[i]; - if (st) { - av_free(st->priv_data); - av_free(st->codec->extradata); - } - av_free(st); - } - return -1; } #define DO_2BITS(bits, var, defval) \ @@ -636,9 +625,7 @@ static int asf_get_packet(AVFormatContext *s) if (packet_length < asf->hdr.min_pktsize) padsize += asf->hdr.min_pktsize - packet_length; asf->packet_padsize = padsize; -#ifdef DEBUG - printf("packet: size=%d padsize=%d left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left); -#endif + dprintf(s, "packet: size=%d padsize=%d left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left); return 0; } @@ -936,7 +923,6 @@ static int asf_read_close(AVFormatContext *s) asf_reset_header(s); for(i=0;i<s->nb_streams;i++) { AVStream *st = s->streams[i]; - av_free(st->priv_data); av_free(st->codec->palctrl); } return 0; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/avformat.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/avformat.h @@ -22,7 +22,7 @@ #define FFMPEG_AVFORMAT_H #define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 16 +#define LIBAVFORMAT_VERSION_MINOR 17 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -160,13 +160,13 @@ typedef struct AVFormatParameters { enum PixelFormat pix_fmt; int channel; /**< used to select dv channel */ const char *standard; /**< tv standard, NTSC, PAL, SECAM */ - int mpeg2ts_raw:1; /**< force raw MPEG2 transport stream output, if possible */ - int mpeg2ts_compute_pcr:1; /**< compute exact PCR for each transport - stream packet (only meaningful if - mpeg2ts_raw is TRUE) */ - int initial_pause:1; /**< do not begin to play the stream - immediately (RTSP only) */ - int prealloced_context:1; + unsigned int mpeg2ts_raw:1; /**< force raw MPEG2 transport stream output, if possible */ + unsigned int mpeg2ts_compute_pcr:1; /**< compute exact PCR for each transport + stream packet (only meaningful if + mpeg2ts_raw is TRUE) */ + unsigned int initial_pause:1; /**< do not begin to play the stream + immediately (RTSP only) */ + unsigned int prealloced_context:1; #if LIBAVFORMAT_VERSION_INT < (53<<16) enum CodecID video_codec_id; enum CodecID audio_codec_id; @@ -391,6 +391,8 @@ typedef struct AVStream { char *filename; /**< source filename of the stream */ int disposition; /**< AV_DISPOSITION_* bitfield */ + + AVProbeData probe_data; } AVStream; #define AV_PROGRAM_RUNNING 1 @@ -555,6 +557,14 @@ typedef struct AVFormatContext { */ int debug; #define FF_FDEBUG_TS 0x0001 + + /** + * raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + struct AVPacketList *raw_packet_buffer; } AVFormatContext; typedef struct AVPacketList { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/avidec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/avidec.c @@ -1,6 +1,6 @@ /* * AVI demuxer - * Copyright (c) 2001 Fabrice Bellard. + * Copyright (c) 2001 Fabrice Bellard * * This file is part of FFmpeg. * @@ -101,7 +101,7 @@ static int get_riff(AVIContext *avi, ByteIOContext *pb) return -1; if(header[7] == 0x19) - av_log(NULL, AV_LOG_INFO, "file has been generated with a totally broken muxer\n"); + av_log(NULL, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n"); return 0; } @@ -262,7 +262,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) switch(tag) { case MKTAG('L', 'I', 'S', 'T'): - /* ignored, except when start of video packets */ + /* Ignored, except at start of video packets. */ tag1 = get_le32(pb); #ifdef DEBUG print_tag("list", tag1, 0); @@ -284,7 +284,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) case MKTAG('a', 'm', 'v', 'h'): amv_file_format=1; case MKTAG('a', 'v', 'i', 'h'): - /* avi header */ + /* AVI header */ /* using frame_period is bad idea */ frame_period = get_le32(pb); bit_rate = get_le32(pb) * 8; @@ -330,7 +330,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) /* * After some consideration -- I don't think we - * have to support anything but DV in a type1 AVIs. + * have to support anything but DV in type1 AVIs. */ if (s->nb_streams != 1) goto fail; @@ -362,7 +362,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) } /* * else, leave duration alone; timing estimation in utils.c - * will make a guess based on bit rate. + * will make a guess based on bitrate. */ stream_index = s->nb_streams - 1; @@ -380,7 +380,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) ast->scale = get_le32(pb); ast->rate = get_le32(pb); if(!(ast->scale && ast->rate)){ - av_log(s, AV_LOG_WARNING, "Scale/Rate is %u/%u which is invalid. (This file has been generated by broken software)\n", ast->scale, ast->rate); + av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate); if(frame_period){ ast->rate = 1000000; ast->scale = frame_period; @@ -469,9 +469,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly get_byte(pb); - /* Extract palette from extradata if bpp <= 8 */ - /* This code assumes that extradata contains only palette */ - /* This is true for all paletted codecs implemented in ffmpeg */ + /* Extract palette from extradata if bpp <= 8. */ + /* This code assumes that extradata contains only palette. */ + /* This is true for all paletted codecs implemented in FFmpeg. */ if (st->codec->extradata_size && (st->codec->bits_per_sample <= 8)) { st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); #ifdef WORDS_BIGENDIAN @@ -490,7 +490,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_tag = tag1; st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1); - st->need_parsing = AVSTREAM_PARSE_HEADERS; // this is needed to get the pict type which is needed for generating correct pts + st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts. // url_fskip(pb, size - 5 * 4); break; case CODEC_TYPE_AUDIO: @@ -502,9 +502,11 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ url_fskip(pb, 1); /* Force parsing as several audio frames can be in - * one packet and timestamps refer to packet start*/ + * one packet and timestamps refer to packet start. */ st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; - /* ADTS header is in extradata, AAC without header must be stored as exact frames, parser not needed and it will fail */ + /* ADTS header is in extradata, AAC without header must be + * stored as exact frames. Parser not needed and it will + * fail. */ if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) st->need_parsing = AVSTREAM_PARSE_NONE; /* AVI files with Xan DPCM audio (wrongly) declare PCM @@ -581,8 +583,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) break; default: if(size > 1000000){ - av_log(s, AV_LOG_ERROR, "well something went wrong during header parsing, " - "ill ignore it and try to continue anyway\n"); + av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " + "I will ignore it and try to continue anyway.\n"); avi->movi_list = url_ftell(pb) - 4; avi->movi_end = url_fsize(pb); goto end_of_header; @@ -597,10 +599,6 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) /* check stream number */ if (stream_index != s->nb_streams - 1) { fail: - for(i=0;i<s->nb_streams;i++) { - av_freep(&s->streams[i]->codec->extradata); - av_freep(&s->streams[i]); - } return -1; } @@ -609,7 +607,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) avi->index_loaded = 1; avi->non_interleaved |= guess_ni_flag(s); if(avi->non_interleaved) { - av_log(s, AV_LOG_INFO, "Non interleaved AVI\n"); + av_log(s, AV_LOG_INFO, "non-interleaved AVI\n"); clean_index(s); } @@ -711,7 +709,7 @@ resync: pkt->destruct = dstr; pkt->flags |= PKT_FLAG_KEY; } else { - /* XXX: how to handle B frames in avi ? */ + /* XXX: How to handle B-frames in AVI? */ pkt->dts = ast->frame_offset; // pkt->dts += ast->start; if(ast->sample_size) @@ -782,7 +780,7 @@ resync: && d[1] >= '0' && d[1] <= '9'){ n= (d[0] - '0') * 10 + (d[1] - '0'); }else{ - n= 100; //invalid stream id + n= 100; //invalid stream ID } //parse ##dc/##wb @@ -806,7 +804,7 @@ resync: n=1; st = st1; ast = ast1; - av_log(s, AV_LOG_WARNING, "Invalid stream+prefix combination, assuming audio\n"); + av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n"); } } @@ -861,8 +859,8 @@ resync: return -1; } -/* XXX: we make the implicit supposition that the position are sorted - for each stream */ +/* XXX: We make the implicit supposition that the positions are sorted + for each stream. */ static int avi_read_idx1(AVFormatContext *s, int size) { AVIContext *avi = s->priv_data; @@ -877,7 +875,7 @@ static int avi_read_idx1(AVFormatContext *s, int size) if (nb_index_entries <= 0) return -1; - /* read the entries and sort them in each stream component */ + /* Read the entries and sort them in each stream component. */ for(i = 0; i < nb_index_entries; i++) { tag = get_le32(pb); flags = get_le32(pb); @@ -1009,7 +1007,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp assert(stream_index == 0); /* Feed the DV video stream version of the timestamp to the */ - /* DV demux so it can synth correct timestamps */ + /* DV demux so it can synthesize correct timestamps. */ dv_offset_reset(avi->dv_demux, timestamp); url_fseek(s->pb, pos, SEEK_SET); @@ -1064,8 +1062,6 @@ static int avi_read_close(AVFormatContext *s) for(i=0;i<s->nb_streams;i++) { AVStream *st = s->streams[i]; - AVIStream *ast = st->priv_data; - av_free(ast); av_free(st->codec->palctrl); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/electronicarts.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/electronicarts.c @@ -1,5 +1,6 @@ /* Electronic Arts Multimedia File Demuxer * Copyright (c) 2004 The ffmpeg Project + * Copyright (c) 2006-2008 Peter Ross * * This file is part of FFmpeg. * @@ -45,6 +46,7 @@ #define MV0K_TAG MKTAG('M', 'V', '0', 'K') #define MV0F_TAG MKTAG('M', 'V', '0', 'F') #define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */ +#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV i-frame */ typedef struct EaDemuxContext { int big_endian; @@ -299,6 +301,11 @@ static int process_ea_header(AVFormatContext *s) { err = process_audio_header_sead(s); break; + case MVIh_TAG : + ea->video_codec = CODEC_ID_CMV; + ea->time_base = (AVRational){0,0}; + break; + case MVhd_TAG : err = process_video_header_vp6(s); break; @@ -441,9 +448,17 @@ static int ea_read_packet(AVFormatContext *s, packet_read = 1; break; + case MVIh_TAG: + key = PKT_FLAG_KEY; + case MVIf_TAG: + url_fseek(pb, -8, SEEK_CUR); // include chunk preamble + chunk_size += 8; + goto get_video_packet; + case MV0K_TAG: key = PKT_FLAG_KEY; case MV0F_TAG: +get_video_packet: ret = av_get_packet(pb, pkt, chunk_size); if (ret != chunk_size) ret = AVERROR_IO; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/ffm.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/ffm.h @@ -48,7 +48,7 @@ typedef struct FFMContext { int first_packet; /* true if first packet, needed to set the discontinuity tag */ int packet_size; int frame_offset; - int64_t pts; + int64_t dts; uint8_t *packet_ptr, *packet_end; uint8_t packet[FFM_PACKET_SIZE]; } FFMContext; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/ffmdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/ffmdec.c @@ -99,7 +99,7 @@ static int ffm_read_data(AVFormatContext *s, retry_read: get_be16(pb); /* PACKET_ID */ fill_size = get_be16(pb); - ffm->pts = get_be64(pb); + ffm->dts = get_be64(pb); frame_offset = get_be16(pb); get_buffer(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); @@ -156,18 +156,18 @@ static void ffm_seek1(AVFormatContext *s, offset_t pos1) url_fseek(pb, pos, SEEK_SET); } -static int64_t get_pts(AVFormatContext *s, offset_t pos) +static int64_t get_dts(AVFormatContext *s, offset_t pos) { ByteIOContext *pb = s->pb; - int64_t pts; + int64_t dts; ffm_seek1(s, pos); url_fskip(pb, 4); - pts = get_be64(pb); + dts = get_be64(pb); #ifdef DEBUG_SEEK av_log(s, AV_LOG_DEBUG, "pts=%0.6f\n", pts / 1000000.0); #endif - return pts; + return dts; } static void adjust_write_index(AVFormatContext *s) @@ -184,18 +184,18 @@ static void adjust_write_index(AVFormatContext *s) pos_min = 0; pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE; - pts_start = get_pts(s, pos_min); + pts_start = get_dts(s, pos_min); - pts = get_pts(s, pos_max); + pts = get_dts(s, pos_max); if (pts - 100000 > pts_start) goto end; ffm->write_index = FFM_PACKET_SIZE; - pts_start = get_pts(s, pos_min); + pts_start = get_dts(s, pos_min); - pts = get_pts(s, pos_max); + pts = get_dts(s, pos_max); if (pts - 100000 <= pts_start) { while (1) { @@ -207,7 +207,7 @@ static void adjust_write_index(AVFormatContext *s) if (newpos == pos_min) break; - newpts = get_pts(s, newpos); + newpts = get_dts(s, newpos); if (newpts - 100000 <= pts) { pos_max = newpos; @@ -220,7 +220,7 @@ static void adjust_write_index(AVFormatContext *s) } //printf("Adjusted write index from %"PRId64" to %"PRId64": pts=%0.6f\n", orig_write_index, ffm->write_index, pts / 1000000.); - //printf("pts range %0.6f - %0.6f\n", get_pts(s, 0) / 1000000. , get_pts(s, ffm->file_size - 2 * FFM_PACKET_SIZE) / 1000000. ); + //printf("pts range %0.6f - %0.6f\n", get_dts(s, 0) / 1000000. , get_dts(s, ffm->file_size - 2 * FFM_PACKET_SIZE) / 1000000. ); end: url_fseek(pb, ptr, SEEK_SET); @@ -310,6 +310,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) codec->frame_skip_cmp = get_be32(pb); codec->rc_buffer_aggressivity = av_int2dbl(get_be64(pb)); codec->codec_tag = get_be32(pb); + codec->thread_count = get_byte(pb); break; case CODEC_TYPE_AUDIO: codec->sample_rate = get_be32(pb); @@ -336,7 +337,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet; ffm->frame_offset = 0; - ffm->pts = 0; + ffm->dts = 0; ffm->read_state = READ_HEADER; ffm->first_packet = 1; return 0; @@ -430,8 +431,8 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in pos_min = 0; pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE; while (pos_min <= pos_max) { - pts_min = get_pts(s, pos_min); - pts_max = get_pts(s, pos_max); + pts_min = get_dts(s, pos_min); + pts_max = get_dts(s, pos_max); /* linear interpolation */ pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) / (double)(pts_max - pts_min); @@ -440,7 +441,7 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in pos = pos_min; else if (pos >= pos_max) pos = pos_max; - pts = get_pts(s, pos); + pts = get_dts(s, pos); /* check if we are lucky */ if (pts == wanted_pts) { goto found; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/ffmenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/ffmenc.c @@ -37,7 +37,7 @@ static void flush_packet(AVFormatContext *s) /* put header */ put_be16(pb, PACKET_ID); put_be16(pb, fill_size); - put_be64(pb, ffm->pts); + put_be64(pb, ffm->dts); h = ffm->frame_offset; if (ffm->first_packet) h |= 0x8000; @@ -47,7 +47,6 @@ static void flush_packet(AVFormatContext *s) /* prepare next packet */ ffm->frame_offset = 0; /* no key frame */ - ffm->pts = 0; /* no pts */ ffm->packet_ptr = ffm->packet; ffm->first_packet = 0; } @@ -55,15 +54,15 @@ static void flush_packet(AVFormatContext *s) /* 'first' is true if first data of a frame */ static void ffm_write_data(AVFormatContext *s, const uint8_t *buf, int size, - int64_t pts, int header) + int64_t dts, int header) { FFMContext *ffm = s->priv_data; int len; - if (header && ffm->frame_offset == 0) + if (header && ffm->frame_offset == 0) { ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; - if (header && ffm->pts == 0) - ffm->pts = pts; + ffm->dts = dts; + } /* write as many packets as needed */ while (size > 0) { @@ -75,13 +74,8 @@ static void ffm_write_data(AVFormatContext *s, ffm->packet_ptr += len; buf += len; size -= len; - if (ffm->packet_ptr >= ffm->packet_end) { - /* special case : no pts in packet : we leave the current one */ - if (ffm->pts == 0) - ffm->pts = pts; - + if (ffm->packet_ptr >= ffm->packet_end) flush_packet(s); - } } } @@ -159,6 +153,7 @@ static int ffm_write_header(AVFormatContext *s) put_be32(pb, codec->frame_skip_cmp); put_be64(pb, av_dbl2int(codec->rc_buffer_aggressivity)); put_be32(pb, codec->codec_tag); + put_byte(pb, codec->thread_count); break; case CODEC_TYPE_AUDIO: put_be32(pb, codec->sample_rate); @@ -185,7 +180,7 @@ static int ffm_write_header(AVFormatContext *s) ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; assert(ffm->packet_end >= ffm->packet); ffm->frame_offset = 0; - ffm->pts = 0; + ffm->dts = 0; ffm->first_packet = 1; return 0; @@ -193,11 +188,11 @@ static int ffm_write_header(AVFormatContext *s) static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) { - int64_t pts; - uint8_t header[FRAME_HEADER_SIZE]; + int64_t dts; + uint8_t header[FRAME_HEADER_SIZE+4]; int header_size = FRAME_HEADER_SIZE; - pts = s->timestamp + pkt->pts; + dts = s->timestamp + pkt->dts; /* packet size & key_frame */ header[0] = pkt->stream_index; header[1] = 0; @@ -205,14 +200,14 @@ static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) header[1] |= FLAG_KEY_FRAME; AV_WB24(header+2, pkt->size); AV_WB24(header+5, pkt->duration); - AV_WB64(header+8, pts); + AV_WB64(header+8, s->timestamp + pkt->pts); if (pkt->pts != pkt->dts) { header[1] |= FLAG_DTS; AV_WB32(header+16, pkt->pts - pkt->dts); header_size += 4; } - ffm_write_data(s, header, header_size, pts, 1); - ffm_write_data(s, pkt->data, pkt->size, pts, 0); + ffm_write_data(s, header, header_size, dts, 1); + ffm_write_data(s, pkt->data, pkt->size, dts, 0); return 0; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/flic.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/flic.c @@ -54,12 +54,25 @@ static int flic_probe(AVProbeData *p) { int magic_number; + if(p->buf_size < FLIC_HEADER_SIZE) + return 0; + magic_number = AV_RL16(&p->buf[4]); if ((magic_number != FLIC_FILE_MAGIC_1) && (magic_number != FLIC_FILE_MAGIC_2) && (magic_number != FLIC_FILE_MAGIC_3)) return 0; + if(AV_RL16(&p->buf[0x10]) != FLIC_CHUNK_MAGIC_1){ + if(AV_RL32(&p->buf[0x10]) > 2000) + return 0; + } + + if( AV_RL16(&p->buf[0x08]) > 4096 + || AV_RL16(&p->buf[0x0A]) > 4096) + return 0; + + return AVPROBE_SCORE_MAX; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/gifdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/gifdec.c @@ -1,590 +0,0 @@ -/* - * GIF demuxer - * Copyright (c) 2003 Fabrice Bellard. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" - -//#define DEBUG - -#define MAXBITS 12 -#define SIZTABLE (1<<MAXBITS) - -#define GCE_DISPOSAL_NONE 0 -#define GCE_DISPOSAL_INPLACE 1 -#define GCE_DISPOSAL_BACKGROUND 2 -#define GCE_DISPOSAL_RESTORE 3 - -typedef struct GifState { - int screen_width; - int screen_height; - int bits_per_pixel; - int background_color_index; - int transparent_color_index; - int color_resolution; - uint8_t *image_buf; - int image_linesize; - uint32_t *image_palette; - int pix_fmt; - - /* after the frame is displayed, the disposal method is used */ - int gce_disposal; - /* delay during which the frame is shown */ - int gce_delay; - - /* LZW compatible decoder */ - ByteIOContext *f; - int eob_reached; - uint8_t *pbuf, *ebuf; - int bbits; - unsigned int bbuf; - - int cursize; /* The current code size */ - int curmask; - int codesize; - int clear_code; - int end_code; - int newcodes; /* First available code */ - int top_slot; /* Highest code for current size */ - int slot; /* Last read code */ - int fc, oc; - uint8_t *sp; - uint8_t stack[SIZTABLE]; - uint8_t suffix[SIZTABLE]; - uint16_t prefix[SIZTABLE]; - - /* aux buffers */ - uint8_t global_palette[256 * 3]; - uint8_t local_palette[256 * 3]; - uint8_t buf[256]; -} GifState; - - -static const uint8_t gif87a_sig[6] = "GIF87a"; -static const uint8_t gif89a_sig[6] = "GIF89a"; - -static const uint16_t mask[17] = -{ - 0x0000, 0x0001, 0x0003, 0x0007, - 0x000F, 0x001F, 0x003F, 0x007F, - 0x00FF, 0x01FF, 0x03FF, 0x07FF, - 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF -}; - -/* Probe gif video format or gif image format. The current heuristic - supposes the gif87a is always a single image. For gif89a, we - consider it as a video only if a GCE extension is present in the - first kilobyte. */ -static int gif_video_probe(AVProbeData * pd) -{ - const uint8_t *p, *p_end; - int bits_per_pixel, has_global_palette, ext_code, ext_len; - int gce_flags, gce_disposal; - - if (pd->buf_size < 24 || - memcmp(pd->buf, gif89a_sig, 6) != 0) - return 0; - p_end = pd->buf + pd->buf_size; - p = pd->buf + 6; - bits_per_pixel = (p[4] & 0x07) + 1; - has_global_palette = (p[4] & 0x80); - p += 7; - if (has_global_palette) - p += (1 << bits_per_pixel) * 3; - for(;;) { - if (p >= p_end) - return 0; - if (*p != '!') - break; - p++; - if (p >= p_end) - return 0; - ext_code = *p++; - if (p >= p_end) - return 0; - ext_len = *p++; - if (ext_code == 0xf9) { - if (p >= p_end) - return 0; - /* if GCE extension found with gce_disposal != 0: it is - likely to be an animation */ - gce_flags = *p++; - gce_disposal = (gce_flags >> 2) & 0x7; - if (gce_disposal != 0) - return AVPROBE_SCORE_MAX; - else - return 0; - } - for(;;) { - if (ext_len == 0) - break; - p += ext_len; - if (p >= p_end) - return 0; - ext_len = *p++; - } - } - return 0; -} - -static void GLZWDecodeInit(GifState * s, int csize) -{ - /* read buffer */ - s->eob_reached = 0; - s->pbuf = s->buf; - s->ebuf = s->buf; - s->bbuf = 0; - s->bbits = 0; - - /* decoder */ - s->codesize = csize; - s->cursize = s->codesize + 1; - s->curmask = mask[s->cursize]; - s->top_slot = 1 << s->cursize; - s->clear_code = 1 << s->codesize; - s->end_code = s->clear_code + 1; - s->slot = s->newcodes = s->clear_code + 2; - s->oc = s->fc = 0; - s->sp = s->stack; -} - -/* XXX: optimize */ -static inline int GetCode(GifState * s) -{ - int c, sizbuf; - uint8_t *ptr; - - while (s->bbits < s->cursize) { - ptr = s->pbuf; - if (ptr >= s->ebuf) { - if (!s->eob_reached) { - sizbuf = get_byte(s->f); - s->ebuf = s->buf + sizbuf; - s->pbuf = s->buf; - if (sizbuf > 0) { - get_buffer(s->f, s->buf, sizbuf); - } else { - s->eob_reached = 1; - } - } - ptr = s->pbuf; - } - s->bbuf |= ptr[0] << s->bbits; - ptr++; - s->pbuf = ptr; - s->bbits += 8; - } - c = s->bbuf & s->curmask; - s->bbuf >>= s->cursize; - s->bbits -= s->cursize; - return c; -} - -/* NOTE: the algorithm here is inspired from the LZW GIF decoder - written by Steven A. Bennett in 1987. */ -/* return the number of byte decoded */ -static int GLZWDecode(GifState * s, uint8_t * buf, int len) -{ - int l, c, code, oc, fc; - uint8_t *sp; - - if (s->end_code < 0) - return 0; - - l = len; - sp = s->sp; - oc = s->oc; - fc = s->fc; - - while (sp > s->stack) { - *buf++ = *(--sp); - if ((--l) == 0) - goto the_end; - } - - for (;;) { - c = GetCode(s); - if (c == s->end_code) { - s->end_code = -1; - break; - } else if (c == s->clear_code) { - s->cursize = s->codesize + 1; - s->curmask = mask[s->cursize]; - s->slot = s->newcodes; - s->top_slot = 1 << s->cursize; - while ((c = GetCode(s)) == s->clear_code); - if (c == s->end_code) { - s->end_code = -1; - break; - } - /* test error */ - if (c >= s->slot) - c = 0; - fc = oc = c; - *buf++ = c; - if ((--l) == 0) - break; - } else { - code = c; - if (code >= s->slot) { - *sp++ = fc; - code = oc; - } - while (code >= s->newcodes) { - *sp++ = s->suffix[code]; - code = s->prefix[code]; - } - *sp++ = code; - if (s->slot < s->top_slot) { - s->suffix[s->slot] = fc = code; - s->prefix[s->slot++] = oc; - oc = c; - } - if (s->slot >= s->top_slot) { - if (s->cursize < MAXBITS) { - s->top_slot <<= 1; - s->curmask = mask[++s->cursize]; - } - } - while (sp > s->stack) { - *buf++ = *(--sp); - if ((--l) == 0) - goto the_end; - } - } - } - the_end: - s->sp = sp; - s->oc = oc; - s->fc = fc; - return len - l; -} - -static int gif_read_image(GifState *s) -{ - ByteIOContext *f = s->f; - int left, top, width, height, bits_per_pixel, code_size, flags; - int is_interleaved, has_local_palette, y, x, pass, y1, linesize, n, i; - uint8_t *ptr, *line, *d, *spal, *palette, *sptr, *ptr1; - - left = get_le16(f); - top = get_le16(f); - width = get_le16(f); - height = get_le16(f); - flags = get_byte(f); - is_interleaved = flags & 0x40; - has_local_palette = flags & 0x80; - bits_per_pixel = (flags & 0x07) + 1; -#ifdef DEBUG - printf("gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); -#endif - - if (has_local_palette) { - get_buffer(f, s->local_palette, 3 * (1 << bits_per_pixel)); - palette = s->local_palette; - } else { - palette = s->global_palette; - bits_per_pixel = s->bits_per_pixel; - } - - /* verify that all the image is inside the screen dimensions */ - if (left + width > s->screen_width || - top + height > s->screen_height) - return AVERROR(EINVAL); - - /* build the palette */ - if (s->pix_fmt == PIX_FMT_RGB24) { - line = av_malloc(width); - if (!line) - return AVERROR(ENOMEM); - } else { - n = (1 << bits_per_pixel); - spal = palette; - for(i = 0; i < n; i++) { - s->image_palette[i] = (0xff << 24) | - (spal[0] << 16) | (spal[1] << 8) | (spal[2]); - spal += 3; - } - for(; i < 256; i++) - s->image_palette[i] = (0xff << 24); - /* handle transparency */ - if (s->transparent_color_index >= 0) - s->image_palette[s->transparent_color_index] = 0; - line = NULL; - } - - /* now get the image data */ - s->f = f; - code_size = get_byte(f); - GLZWDecodeInit(s, code_size); - - /* read all the image */ - linesize = s->image_linesize; - ptr1 = s->image_buf + top * linesize + (left * 3); - ptr = ptr1; - pass = 0; - y1 = 0; - for (y = 0; y < height; y++) { - if (s->pix_fmt == PIX_FMT_RGB24) { - /* transcode to RGB24 */ - GLZWDecode(s, line, width); - d = ptr; - sptr = line; - for(x = 0; x < width; x++) { - spal = palette + sptr[0] * 3; - d[0] = spal[0]; - d[1] = spal[1]; - d[2] = spal[2]; - d += 3; - sptr++; - } - } else { - GLZWDecode(s, ptr, width); - } - if (is_interleaved) { - switch(pass) { - default: - case 0: - case 1: - y1 += 8; - ptr += linesize * 8; - if (y1 >= height) { - y1 = pass == 0 ? 4 : 2; - ptr = ptr1 + linesize * y1; - pass++; - } - break; - case 2: - y1 += 4; - ptr += linesize * 4; - if (y1 >= height) { - y1 = 1; - ptr = ptr1 + linesize; - pass++; - } - break; - case 3: - y1 += 2; - ptr += linesize * 2; - break; - } - } else { - ptr += linesize; - } - } - av_free(line); - - /* read the garbage data until end marker is found */ - while (!s->eob_reached) - GetCode(s); - return 0; -} - -static int gif_read_extension(GifState *s) -{ - ByteIOContext *f = s->f; - int ext_code, ext_len, i, gce_flags, gce_transparent_index; - - /* extension */ - ext_code = get_byte(f); - ext_len = get_byte(f); -#ifdef DEBUG - printf("gif: ext_code=0x%x len=%d\n", ext_code, ext_len); -#endif - switch(ext_code) { - case 0xf9: - if (ext_len != 4) - goto discard_ext; - s->transparent_color_index = -1; - gce_flags = get_byte(f); - s->gce_delay = get_le16(f); - gce_transparent_index = get_byte(f); - if (gce_flags & 0x01) - s->transparent_color_index = gce_transparent_index; - else - s->transparent_color_index = -1; - s->gce_disposal = (gce_flags >> 2) & 0x7; -#ifdef DEBUG - printf("gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n", - gce_flags, s->gce_delay, - s->transparent_color_index, s->gce_disposal); -#endif - ext_len = get_byte(f); - break; - } - - /* NOTE: many extension blocks can come after */ - discard_ext: - while (ext_len != 0) { - for (i = 0; i < ext_len; i++) - get_byte(f); - ext_len = get_byte(f); -#ifdef DEBUG - printf("gif: ext_len1=%d\n", ext_len); -#endif - } - return 0; -} - -static int gif_read_header1(GifState *s) -{ - ByteIOContext *f = s->f; - uint8_t sig[6]; - int ret, v, n; - int has_global_palette; - - /* read gif signature */ - ret = get_buffer(f, sig, 6); - if (ret != 6) - return -1; - if (memcmp(sig, gif87a_sig, 6) != 0 && - memcmp(sig, gif89a_sig, 6) != 0) - return -1; - - /* read screen header */ - s->transparent_color_index = -1; - s->screen_width = get_le16(f); - s->screen_height = get_le16(f); - if( (unsigned)s->screen_width > 32767 - || (unsigned)s->screen_height > 32767){ - av_log(NULL, AV_LOG_ERROR, "picture size too large\n"); - return -1; - } - - v = get_byte(f); - s->color_resolution = ((v & 0x70) >> 4) + 1; - has_global_palette = (v & 0x80); - s->bits_per_pixel = (v & 0x07) + 1; - s->background_color_index = get_byte(f); - get_byte(f); /* ignored */ -#ifdef DEBUG - printf("gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", - s->screen_width, s->screen_height, s->bits_per_pixel, - has_global_palette); -#endif - if (has_global_palette) { - n = 1 << s->bits_per_pixel; - get_buffer(f, s->global_palette, n * 3); - } - return 0; -} - -static int gif_parse_next_image(GifState *s) -{ - ByteIOContext *f = s->f; - int ret, code; - - for (;;) { - code = url_fgetc(f); -#ifdef DEBUG - printf("gif: code=%02x '%c'\n", code, code); -#endif - switch (code) { - case ',': - if (gif_read_image(s) < 0) - return AVERROR(EIO); - ret = 0; - goto the_end; - case ';': - /* end of image */ - ret = AVERROR(EIO); - goto the_end; - case '!': - if (gif_read_extension(s) < 0) - return AVERROR(EIO); - break; - case EOF: - default: - /* error or errneous EOF */ - ret = AVERROR(EIO); - goto the_end; - } - } - the_end: - return ret; -} - -static int gif_read_header(AVFormatContext * s1, - AVFormatParameters * ap) -{ - GifState *s = s1->priv_data; - ByteIOContext *f = s1->pb; - AVStream *st; - - s->f = f; - if (gif_read_header1(s) < 0) - return -1; - - /* allocate image buffer */ - s->image_linesize = s->screen_width * 3; - s->image_buf = av_malloc(s->screen_height * s->image_linesize); - if (!s->image_buf) - return AVERROR(ENOMEM); - s->pix_fmt = PIX_FMT_RGB24; - /* now we are ready: build format streams */ - st = av_new_stream(s1, 0); - if (!st) - return -1; - - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->time_base.den = 5; - st->codec->time_base.num = 1; - /* XXX: check if screen size is always valid */ - st->codec->width = s->screen_width; - st->codec->height = s->screen_height; - st->codec->pix_fmt = PIX_FMT_RGB24; - return 0; -} - -static int gif_read_packet(AVFormatContext * s1, - AVPacket * pkt) -{ - GifState *s = s1->priv_data; - int ret; - - ret = gif_parse_next_image(s); - if (ret < 0) - return ret; - - /* XXX: avoid copying */ - if (av_new_packet(pkt, s->screen_width * s->screen_height * 3)) { - return AVERROR(EIO); - } - pkt->stream_index = 0; - memcpy(pkt->data, s->image_buf, s->screen_width * s->screen_height * 3); - return 0; -} - -static int gif_read_close(AVFormatContext *s1) -{ - GifState *s = s1->priv_data; - av_free(s->image_buf); - return 0; -} - -AVInputFormat gif_demuxer = -{ - "gif", - NULL_IF_CONFIG_SMALL("GIF format"), - sizeof(GifState), - gif_video_probe, - gif_read_header, - gif_read_packet, - gif_read_close, -}; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/isom.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/isom.c @@ -123,6 +123,7 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') }, { CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */ + { CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') }, { CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */ { CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/matroskadec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/matroskadec.c @@ -973,6 +973,82 @@ matroska_parse_info (MatroskaDemuxContext *matroska) } static int +matroska_decode_buffer(uint8_t** buf, int* buf_size, MatroskaTrack *track) +{ + uint8_t* data = *buf; + int isize = *buf_size; + uint8_t* pkt_data = NULL; + int pkt_size = isize; + int result = 0; + int olen; + + switch (track->encoding_algo) { + case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: + return track->encoding_settings_len; + case MATROSKA_TRACK_ENCODING_COMP_LZO: + do { + olen = pkt_size *= 3; + pkt_data = av_realloc(pkt_data, + pkt_size+LZO_OUTPUT_PADDING); + result = lzo1x_decode(pkt_data, &olen, data, &isize); + } while (result==LZO_OUTPUT_FULL && pkt_size<10000000); + if (result) + goto failed; + pkt_size -= olen; + break; +#ifdef CONFIG_ZLIB + case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { + z_stream zstream = {0}; + if (inflateInit(&zstream) != Z_OK) + return -1; + zstream.next_in = data; + zstream.avail_in = isize; + do { + pkt_size *= 3; + pkt_data = av_realloc(pkt_data, pkt_size); + zstream.avail_out = pkt_size - zstream.total_out; + zstream.next_out = pkt_data + zstream.total_out; + result = inflate(&zstream, Z_NO_FLUSH); + } while (result==Z_OK && pkt_size<10000000); + pkt_size = zstream.total_out; + inflateEnd(&zstream); + if (result != Z_STREAM_END) + goto failed; + break; + } +#endif +#ifdef CONFIG_BZLIB + case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { + bz_stream bzstream = {0}; + if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) + return -1; + bzstream.next_in = data; + bzstream.avail_in = isize; + do { + pkt_size *= 3; + pkt_data = av_realloc(pkt_data, pkt_size); + bzstream.avail_out = pkt_size - bzstream.total_out_lo32; + bzstream.next_out = pkt_data + bzstream.total_out_lo32; + result = BZ2_bzDecompress(&bzstream); + } while (result==BZ_OK && pkt_size<10000000); + pkt_size = bzstream.total_out_lo32; + BZ2_bzDecompressEnd(&bzstream); + if (result != BZ_STREAM_END) + goto failed; + break; + } +#endif + } + + *buf = pkt_data; + *buf_size = pkt_size; + return 0; + failed: + av_free(pkt_data); + return -1; +} + +static int matroska_add_stream (MatroskaDemuxContext *matroska) { int res = 0; @@ -1534,6 +1610,23 @@ matroska_add_stream (MatroskaDemuxContext *matroska) } } + if (track->codec_priv_size && track->encoding_scope & 2) { + uint8_t *orig_priv = track->codec_priv; + int offset = matroska_decode_buffer(&track->codec_priv, + &track->codec_priv_size, track); + if (offset > 0) { + track->codec_priv = av_malloc(track->codec_priv_size + offset); + memcpy(track->codec_priv, track->encoding_settings, offset); + memcpy(track->codec_priv+offset, orig_priv, track->codec_priv_size); + track->codec_priv_size += offset; + av_free(orig_priv); + } else if (!offset) { + av_free(orig_priv); + } else + av_log(matroska->ctx, AV_LOG_ERROR, + "Failed to decode codec private data\n"); + } + if (track->type && matroska->num_tracks < ARRAY_SIZE(matroska->tracks)) { matroska->tracks[matroska->num_tracks++] = track; } else { @@ -2801,78 +2894,14 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size, matroska_queue_packet(matroska, pkt); } } else { - int result, offset = 0, ilen, olen, pkt_size = lace_size[n]; + int offset = 0, pkt_size = lace_size[n]; uint8_t *pkt_data = data; if (matroska->tracks[track]->encoding_scope & 1) { - switch (matroska->tracks[track]->encoding_algo) { - case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: - offset = matroska->tracks[track]->encoding_settings_len; - break; - case MATROSKA_TRACK_ENCODING_COMP_LZO: - pkt_data = NULL; - do { - ilen = lace_size[n]; - olen = pkt_size *= 3; - pkt_data = av_realloc(pkt_data, - pkt_size+LZO_OUTPUT_PADDING); - result = lzo1x_decode(pkt_data, &olen, data, &ilen); - } while (result==LZO_OUTPUT_FULL && pkt_size<10000000); - if (result) { - av_free(pkt_data); - continue; - } - pkt_size -= olen; - break; -#ifdef CONFIG_ZLIB - case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { - z_stream zstream = {0}; - pkt_data = NULL; - if (inflateInit(&zstream) != Z_OK) - continue; - zstream.next_in = data; - zstream.avail_in = lace_size[n]; - do { - pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size); - zstream.avail_out = pkt_size - zstream.total_out; - zstream.next_out = pkt_data + zstream.total_out; - result = inflate(&zstream, Z_NO_FLUSH); - } while (result==Z_OK && pkt_size<10000000); - pkt_size = zstream.total_out; - inflateEnd(&zstream); - if (result != Z_STREAM_END) { - av_free(pkt_data); - continue; - } - break; - } -#endif -#ifdef CONFIG_BZLIB - case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { - bz_stream bzstream = {0}; - pkt_data = NULL; - if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) - continue; - bzstream.next_in = data; - bzstream.avail_in = lace_size[n]; - do { - pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size); - bzstream.avail_out = pkt_size - bzstream.total_out_lo32; - bzstream.next_out = pkt_data + bzstream.total_out_lo32; - result = BZ2_bzDecompress(&bzstream); - } while (result==BZ_OK && pkt_size<10000000); - pkt_size = bzstream.total_out_lo32; - BZ2_bzDecompressEnd(&bzstream); - if (result != BZ_STREAM_END) { - av_free(pkt_data); - continue; - } - break; - } -#endif - } + offset = matroska_decode_buffer(&pkt_data, &pkt_size, + matroska->tracks[track]); + if (offset < 0) + continue; } pkt = av_mallocz(sizeof(AVPacket)); @@ -2887,6 +2916,9 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size, memcpy (pkt->data, matroska->tracks[track]->encoding_settings, offset); memcpy (pkt->data+offset, pkt_data, pkt_size); + if (pkt_data != data) + av_free(pkt_data); + if (n == 0) pkt->flags = is_keyframe; pkt->stream_index = stream_index; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mm.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mm.c @@ -52,7 +52,6 @@ #define MM_PALETTE_SIZE (MM_PALETTE_COUNT*3) typedef struct { - AVPaletteControl palette_control; unsigned int audio_pts, video_pts; } MmDemuxContext; @@ -101,7 +100,6 @@ static int mm_read_header(AVFormatContext *s, st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = width; st->codec->height = height; - st->codec->palctrl = &mm->palette_control; av_set_pts_info(st, 64, 1, frame_rate); /* audio stream */ @@ -117,7 +115,6 @@ static int mm_read_header(AVFormatContext *s, av_set_pts_info(st, 64, 1, 8000); /* 8000 hz */ } - mm->palette_control.palette_changed = 0; mm->audio_pts = 0; mm->video_pts = 0; return 0; @@ -129,9 +126,7 @@ static int mm_read_packet(AVFormatContext *s, MmDemuxContext *mm = s->priv_data; ByteIOContext *pb = s->pb; unsigned char preamble[MM_PREAMBLE_SIZE]; - unsigned char pal[MM_PALETTE_SIZE]; unsigned int type, length; - int i; while(1) { @@ -144,22 +139,6 @@ static int mm_read_packet(AVFormatContext *s, switch(type) { case MM_TYPE_PALETTE : - url_fseek(pb, 4, SEEK_CUR); /* unknown data */ - if (get_buffer(pb, pal, MM_PALETTE_SIZE) != MM_PALETTE_SIZE) - return AVERROR(EIO); - url_fseek(pb, length - (4 + MM_PALETTE_SIZE), SEEK_CUR); - - for (i=0; i<MM_PALETTE_COUNT; i++) { - int r = pal[i*3 + 0]; - int g = pal[i*3 + 1]; - int b = pal[i*3 + 2]; - mm->palette_control.palette[i] = (r << 16) | (g << 8) | (b); - /* repeat palette, where each components is multiplied by four */ - mm->palette_control.palette[i+128] = (r << 18) | (g << 10) | (b<<2); - } - mm->palette_control.palette_changed = 1; - break; - case MM_TYPE_INTER : case MM_TYPE_INTRA : case MM_TYPE_INTRA_HH : @@ -174,7 +153,9 @@ static int mm_read_packet(AVFormatContext *s, return AVERROR(EIO); pkt->size = length + MM_PREAMBLE_SIZE; pkt->stream_index = 0; - pkt->pts = mm->video_pts++; + pkt->pts = mm->video_pts; + if (type!=MM_TYPE_PALETTE) + mm->video_pts++; return 0; case MM_TYPE_AUDIO : diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mmf.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mmf.c @@ -29,6 +29,14 @@ typedef struct { static int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 }; +static int mmf_rate(int code) +{ + if((code < 0) || (code > 4)) + return -1; + return mmf_rates[code]; +} + +#ifdef CONFIG_MUXERS static int mmf_rate_code(int rate) { int i; @@ -38,14 +46,6 @@ static int mmf_rate_code(int rate) return -1; } -static int mmf_rate(int code) -{ - if((code < 0) || (code > 4)) - return -1; - return mmf_rates[code]; -} - -#ifdef CONFIG_MUXERS /* Copy of end_tag() from avienc.c, but for big-endian chunk size */ static void end_tag_be(ByteIOContext *pb, offset_t start) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mov.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mov.c @@ -1634,6 +1634,7 @@ static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) } static const MOVParseTableEntry mov_default_parse_table[] = { +{ MKTAG('a','v','s','s'), mov_read_extradata }, { MKTAG('c','o','6','4'), mov_read_stco }, { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */ { MKTAG('d','i','n','f'), mov_read_default }, @@ -1698,6 +1699,7 @@ static int mov_probe(AVProbeData *p) case MKTAG('m','d','a','t'): case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */ case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */ + case MKTAG('f','t','y','p'): return AVPROBE_SCORE_MAX; /* those are more common words, so rate then a bit less */ case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */ @@ -1706,8 +1708,7 @@ static int mov_probe(AVProbeData *p) case MKTAG('j','u','n','k'): case MKTAG('p','i','c','t'): return AVPROBE_SCORE_MAX - 5; - case MKTAG(0x82,0x82,0x7f,0x7d ): - case MKTAG('f','t','y','p'): + case MKTAG(0x82,0x82,0x7f,0x7d): case MKTAG('s','k','i','p'): case MKTAG('u','u','i','d'): case MKTAG('p','r','f','l'): @@ -1899,7 +1900,6 @@ static int mov_read_close(AVFormatContext *s) av_freep(&sc->drefs); if (sc->pb && sc->pb != s->pb) url_fclose(sc->pb); - av_freep(&sc); } if(mov->dv_demux){ for(i=0; i<mov->dv_fctx->nb_streams; i++){ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/movenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/movenc.c @@ -1531,7 +1531,8 @@ static int mov_write_header(AVFormatContext *s) track->mode = mov->mode; track->tag = mov_find_codec_tag(s, track); if (!track->tag) { - av_log(s, AV_LOG_ERROR, "track %d: could not find tag for codec\n", i); + av_log(s, AV_LOG_ERROR, "track %d: could not find tag, " + "codec not currently supported in container\n", i); return -1; } if(st->codec->codec_type == CODEC_TYPE_VIDEO){ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mp3.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mp3.c @@ -185,6 +185,8 @@ static void id3v2_read_ttag(AVFormatContext *s, int taglen, char *dst, int dstle char *q; int len; + if(dstlen > 0) + dst[0]= 0; if(taglen < 1) return; @@ -203,7 +205,7 @@ static void id3v2_read_ttag(AVFormatContext *s, int taglen, char *dst, int dstle break; case 3: /* UTF-8 */ - len = FFMIN(taglen, dstlen); + len = FFMIN(taglen, dstlen-1); get_buffer(s->pb, dst, len); dst[len] = 0; break; @@ -358,37 +360,6 @@ static int id3v1_parse_tag(AVFormatContext *s, const uint8_t *buf) return 0; } -static void id3v1_create_tag(AVFormatContext *s, uint8_t *buf) -{ - int v, i; - - memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */ - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'G'; - strncpy(buf + 3, s->title, 30); - strncpy(buf + 33, s->author, 30); - strncpy(buf + 63, s->album, 30); - v = s->year; - if (v > 0) { - for(i = 0;i < 4; i++) { - buf[96 - i] = '0' + (v % 10); - v = v / 10; - } - } - strncpy(buf + 97, s->comment, 30); - if (s->track != 0) { - buf[125] = 0; - buf[126] = s->track; - } - for(i = 0; i <= ID3v1_GENRE_MAX; i++) { - if (!strcasecmp(s->genre, id3v1_genre_str[i])) { - buf[127] = i; - break; - } - } -} - /* mp3 read */ static int mp3_read_probe(AVProbeData *p) @@ -550,6 +521,37 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) } #ifdef CONFIG_MUXERS +static void id3v1_create_tag(AVFormatContext *s, uint8_t *buf) +{ + int v, i; + + memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */ + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'G'; + strncpy(buf + 3, s->title, 30); + strncpy(buf + 33, s->author, 30); + strncpy(buf + 63, s->album, 30); + v = s->year; + if (v > 0) { + for(i = 0;i < 4; i++) { + buf[96 - i] = '0' + (v % 10); + v = v / 10; + } + } + strncpy(buf + 97, s->comment, 30); + if (s->track != 0) { + buf[125] = 0; + buf[126] = s->track; + } + for(i = 0; i <= ID3v1_GENRE_MAX; i++) { + if (!strcasecmp(s->genre, id3v1_genre_str[i])) { + buf[127] = i; + break; + } + } +} + /* simple formats */ static void id3v2_put_size(AVFormatContext *s, int size) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mpeg.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mpeg.c @@ -459,7 +459,7 @@ static int mpegps_read_packet(AVFormatContext *s, if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) codec_id = CODEC_ID_CAVS; else - codec_id = CODEC_ID_MPEG2VIDEO; + codec_id = CODEC_ID_PROBE; type = CODEC_TYPE_VIDEO; } else if (startcode >= 0x1c0 && startcode <= 0x1df) { type = CODEC_TYPE_AUDIO; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mpegts.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mpegts.c @@ -63,8 +63,8 @@ typedef struct MpegTSSectionFilter { int section_index; int section_h_size; uint8_t *section_buf; - int check_crc:1; - int end_of_section_reached:1; + unsigned int check_crc:1; + unsigned int end_of_section_reached:1; SectionCallback *section_cb; void *opaque; } MpegTSSectionFilter; @@ -334,8 +334,6 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) pid = filter->pid; if (filter->type == MPEGTS_SECTION) av_freep(&filter->u.section_filter.section_buf); - else if (filter->type == MPEGTS_PES) - av_freep(&filter->u.pes_filter.opaque); av_free(filter); ts->pids[pid] = NULL; @@ -349,8 +347,8 @@ static int analyze(const uint8_t *buf, int size, int packet_size, int *index){ memset(stat, 0, packet_size*sizeof(int)); - for(x=i=0; i<size; i++){ - if(buf[i] == 0x47){ + for(x=i=0; i<size-3; i++){ + if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && (buf[i+3] & 0x30)){ stat[x]++; if(stat[x] > best_score){ best_score= stat[x]; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mtv.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mtv.c @@ -46,9 +46,7 @@ typedef struct MTVDemuxContext { unsigned int img_height; // unsigned int img_segment_size; ///< size of image segment unsigned int video_fps; // - unsigned int audio_subsegments; ///< audio subsegments on one segment - - uint8_t audio_packet_count; + unsigned int full_segment_size; } MTVDemuxContext; @@ -67,6 +65,7 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) MTVDemuxContext *mtv = s->priv_data; ByteIOContext *pb = s->pb; AVStream *st; + unsigned int audio_subsegments; url_fskip(pb, 3); @@ -81,15 +80,14 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) mtv->img_height = get_le16(pb); mtv->img_segment_size = get_le16(pb); url_fskip(pb, 4); - mtv->audio_subsegments = get_le16(pb); - mtv->video_fps = (mtv->audio_br / 4) / mtv->audio_subsegments; + audio_subsegments = get_le16(pb); + mtv->full_segment_size = + audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + + mtv->img_segment_size; + mtv->video_fps = (mtv->audio_br / 4) / audio_subsegments; /* FIXME Add sanity check here */ - /* first packet is always audio*/ - - mtv->audio_packet_count = 1; - /* all systems go! init decoders */ /* video - raw rgb565 */ @@ -139,7 +137,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) ret = 0; - if(mtv->audio_subsegments >= mtv->audio_packet_count) + if((url_ftell(pb) - s->data_offset + mtv->img_segment_size) % mtv->full_segment_size) { url_fskip(pb, MTV_AUDIO_PADDING_SIZE); @@ -147,7 +145,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) if(ret != MTV_ASUBCHUNK_DATA_SIZE) return AVERROR(EIO); - mtv->audio_packet_count++; + pkt->pos -= MTV_AUDIO_PADDING_SIZE; pkt->stream_index = AUDIO_SID; }else @@ -167,7 +165,6 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) for(i=0;i<mtv->img_segment_size/2;i++) *((uint16_t *)pkt->data+i) = bswap_16(*((uint16_t *)pkt->data+i)); #endif - mtv->audio_packet_count = 1; pkt->stream_index = VIDEO_SID; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mvi.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mvi.c @@ -0,0 +1,135 @@ +/* + * Motion Pixels MVI Demuxer + * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" + +#define MVI_FRAC_BITS 10 + +#define MVI_AUDIO_STREAM_INDEX 0 +#define MVI_VIDEO_STREAM_INDEX 1 + +typedef struct MviDemuxContext { + unsigned int (*get_int)(ByteIOContext *); + uint32_t audio_data_size; + uint64_t audio_size_counter; + uint64_t audio_frame_size; + int audio_size_left; + int video_frame_size; +} MviDemuxContext; + +static int read_header(AVFormatContext *s, AVFormatParameters *ap) +{ + MviDemuxContext *mvi = s->priv_data; + ByteIOContext *pb = s->pb; + AVStream *ast, *vst; + unsigned int version, frames_count, msecs_per_frame, player_version; + + ast = av_new_stream(s, 0); + if (!ast) + return AVERROR(ENOMEM); + + vst = av_new_stream(s, 0); + if (!vst) + return AVERROR(ENOMEM); + + vst->codec->extradata_size = 2; + vst->codec->extradata = av_mallocz(2 + FF_INPUT_BUFFER_PADDING_SIZE); + + version = get_byte(pb); + vst->codec->extradata[0] = get_byte(pb); + vst->codec->extradata[1] = get_byte(pb); + frames_count = get_le32(pb); + msecs_per_frame = get_le32(pb); + vst->codec->width = get_le16(pb); + vst->codec->height = get_le16(pb); + get_byte(pb); + ast->codec->sample_rate = get_le16(pb); + mvi->audio_data_size = get_le32(pb); + get_byte(pb); + player_version = get_le32(pb); + get_le16(pb); + get_byte(pb); + + if (frames_count == 0 || mvi->audio_data_size == 0) + return AVERROR_INVALIDDATA; + + if (version != 7 || player_version > 213) { + av_log(s, AV_LOG_ERROR, "unhandled version (%d,%d)\n", version, player_version); + return AVERROR_INVALIDDATA; + } + + av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); + ast->codec->codec_type = CODEC_TYPE_AUDIO; + ast->codec->codec_id = CODEC_ID_PCM_U8; + ast->codec->channels = 1; + ast->codec->bits_per_sample = 8; + ast->codec->bit_rate = ast->codec->sample_rate * 8; + + av_set_pts_info(vst, 64, msecs_per_frame, 1000000); + vst->codec->codec_type = CODEC_TYPE_VIDEO; + vst->codec->codec_id = CODEC_ID_MOTIONPIXELS; + vst->codec->pix_fmt = PIX_FMT_RGB555; + + mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? get_le16 : get_le24; + + mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; + mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; + mvi->audio_size_left = mvi->audio_data_size; + + return 0; +} + +static int read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int ret, count; + MviDemuxContext *mvi = s->priv_data; + ByteIOContext *pb = s->pb; + + if (mvi->video_frame_size == 0) { + mvi->video_frame_size = (mvi->get_int)(pb); + if (mvi->audio_size_left == 0) + return AVERROR(EIO); + count = (mvi->audio_size_counter + mvi->audio_frame_size + 512) >> MVI_FRAC_BITS; + if (count > mvi->audio_size_left) + count = mvi->audio_size_left; + if ((ret = av_get_packet(pb, pkt, count)) < 0) + return ret; + pkt->stream_index = MVI_AUDIO_STREAM_INDEX; + mvi->audio_size_left -= count; + mvi->audio_size_counter += mvi->audio_frame_size - (count << MVI_FRAC_BITS); + } else { + if ((ret = av_get_packet(pb, pkt, mvi->video_frame_size)) < 0) + return ret; + pkt->stream_index = MVI_VIDEO_STREAM_INDEX; + mvi->video_frame_size = 0; + } + return 0; +} + +AVInputFormat mvi_demuxer = { + "mvi", + NULL_IF_CONFIG_SMALL("Motion Pixels MVI format"), + sizeof(MviDemuxContext), + NULL, + read_header, + read_packet, + .extensions = "mvi" +}; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mxf.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/mxf.c @@ -349,7 +349,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) { int index = mxf_get_stream_index(s, &klv); if (index < 0) { - av_log(s, AV_LOG_ERROR, "error getting stream index\n"); + av_log(s, AV_LOG_ERROR, "error getting stream index %x\n", AV_RB32(klv.key+12)); goto skip; } if (s->streams[index]->discard == AVDISCARD_ALL) @@ -1015,6 +1015,9 @@ static int mxf_read_close(AVFormatContext *s) case MaterialPackage: av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs); break; + case Track: + mxf->metadata_sets[i] = NULL; /* will be freed later */ + break; default: break; } @@ -1061,7 +1064,7 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti AVInputFormat mxf_demuxer = { "mxf", - NULL_IF_CONFIG_SMALL("MXF format"), + NULL_IF_CONFIG_SMALL("Material eXchange Format"), sizeof(MXFContext), mxf_probe, mxf_read_header, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/nsvdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/nsvdec.c @@ -180,6 +180,7 @@ typedef struct { uint32_t vtag, atag; uint16_t vwidth, vheight; int16_t avsync; + AVRational framerate; //DVDemuxContext* dv_demux; } NSVContext; @@ -428,6 +429,7 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap) framerate= (AVRational){i, 1}; nsv->avsync = get_le16(pb); + nsv->framerate = framerate; #ifdef DEBUG print_tag("NSV NSVs vtag", vtag, 0); print_tag("NSV NSVs atag", atag, 0); @@ -647,8 +649,8 @@ null_chunk_retry: if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) { /* on a nsvs frame we have new information on a/v sync */ pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1); - pkt->dts *= (int64_t)1000 * st[NSV_ST_VIDEO]->time_base.num; - pkt->dts += (int64_t)nsv->avsync * st[NSV_ST_VIDEO]->time_base.den; + pkt->dts *= (int64_t)1000 * nsv->framerate.den; + pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num; PRINT(("NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts)); } nst->frame_offset++; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/nutenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/nutenc.c @@ -650,6 +650,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt){ int store_sp=0; int ret; + if(pkt->pts < 0) + return -1; + if(1LL<<(20+3*nut->header_count) <= url_ftell(bc)) write_headers(nut, bc); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/nuv.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/nuv.c @@ -179,7 +179,7 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) { ctx->a_id = -1; get_codec_data(pb, vst, ast, is_mythtv); - ctx->rtjpg_video = vst->codec->codec_id == CODEC_ID_NUV; + ctx->rtjpg_video = vst && vst->codec->codec_id == CODEC_ID_NUV; return 0; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oggdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oggdec.c @@ -468,16 +468,6 @@ ogg_get_length (AVFormatContext * s) ogg->size = size; ogg_restore (s, 0); - ogg_save (s); - while (!ogg_read_page (s, &i)) { - if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0) - break; - } - if (i == idx) { - s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule); - s->streams[idx]->duration -= s->streams[idx]->start_time; - } - ogg_restore (s, 0); return 0; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oggenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oggenc.c @@ -225,7 +225,7 @@ int ogg_interleave_per_granule(AVFormatContext *s, AVPacket *out, AVPacket *pkt, next_granule = av_rescale_q(next_pkt->pts + next_pkt->duration, st2->time_base, AV_TIME_BASE_Q); cur_granule = av_rescale_q(pkt->pts + pkt->duration, - st->time_base, AV_TIME_BASE_Q); + st->time_base, AV_TIME_BASE_Q); if (next_granule > cur_granule) break; next_point= &(*next_point)->next; @@ -281,7 +281,7 @@ AVOutputFormat ogg_muxer = { "ogg", NULL_IF_CONFIG_SMALL("Ogg"), "application/ogg", - "ogg", + "ogg,ogv", 0, CODEC_ID_FLAC, CODEC_ID_THEORA, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oggparsevorbis.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oggparsevorbis.c @@ -146,7 +146,7 @@ fixup_vorbis_headers(AVFormatContext * as, oggvorbis_private_t *priv, memcpy(&ptr[offset], priv->packet[i], priv->len[i]); offset += priv->len[i]; } - *buf = av_realloc(*buf, offset); + *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE); return offset; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oma.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/oma.c @@ -52,18 +52,22 @@ enum { OMA_CODECID_ATRAC3 = 0, OMA_CODECID_ATRAC3P = 1, + OMA_CODECID_MP3 = 3, + OMA_CODECID_LPCM = 4, + OMA_CODECID_WMA = 5, }; static const AVCodecTag codec_oma_tags[] = { { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, + { CODEC_ID_MP3, OMA_CODECID_MP3 }, }; static int oma_read_header(AVFormatContext *s, AVFormatParameters *ap) { static const uint16_t srate_tab[6] = {320,441,480,882,960,0}; - int ret, ea3_taglen, EA3_pos, framesize, jsflag, samplerate, channel_id; + int ret, ea3_taglen, EA3_pos, framesize, jsflag, samplerate; uint32_t codec_params; int16_t eid; uint8_t buf[EA3_HEADER_SIZE]; @@ -97,21 +101,27 @@ static int oma_read_header(AVFormatContext *s, } codec_params = AV_RB24(&buf[33]); - channel_id = (codec_params >> 10) & 7; - samplerate = srate_tab[(codec_params >> 13) & 7]*100; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); + st->start_time = 0; + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_tag = buf[32]; + st->codec->codec_id = codec_get_id(codec_oma_tags, st->codec->codec_tag); + switch (buf[32]) { case OMA_CODECID_ATRAC3: + samplerate = srate_tab[(codec_params >> 13) & 7]*100; if (samplerate != 44100) av_log(s, AV_LOG_ERROR, "Unsupported sample rate, send sample file to developers: %d\n", samplerate); framesize = (codec_params & 0x3FF) * 8; jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */ - channel_id = 2; + st->codec->channels = 2; + st->codec->sample_rate = samplerate; + st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */ st->codec->extradata_size = 14; @@ -126,28 +136,28 @@ static int oma_read_header(AVFormatContext *s, AV_WL16(&edata[8], jsflag); // coding mode AV_WL16(&edata[10], 1); // always 1 // AV_WL16(&edata[12], 0); // always 0 + + av_set_pts_info(st, 64, 1, st->codec->sample_rate); break; case OMA_CODECID_ATRAC3P: + st->codec->channels = (codec_params >> 10) & 7; framesize = ((codec_params & 0x3FF) * 8) + 8; + st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100; + st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; + av_set_pts_info(st, 64, 1, st->codec->sample_rate); av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n"); break; + case OMA_CODECID_MP3: + st->need_parsing = AVSTREAM_PARSE_FULL; + framesize = 1024; + break; default: av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]); return -1; break; } - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_tag = buf[32]; - st->codec->codec_id = codec_get_id(codec_oma_tags, st->codec->codec_tag); - st->codec->channels = channel_id; - st->codec->sample_rate = samplerate; - st->codec->bit_rate = samplerate * framesize * 8 / 1024; st->codec->block_align = framesize; - - st->start_time = 0; - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - url_fseek(s->pb, EA3_pos + EA3_HEADER_SIZE, SEEK_SET); return 0; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/psxstr.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/psxstr.c @@ -31,16 +31,14 @@ #include "avformat.h" -//#define PRINTSTUFF - #define RIFF_TAG MKTAG('R', 'I', 'F', 'F') #define CDXA_TAG MKTAG('C', 'D', 'X', 'A') -#define RAW_CD_SECTOR_SIZE 2352 +#define RAW_CD_SECTOR_SIZE 2352 #define RAW_CD_SECTOR_DATA_SIZE 2304 -#define VIDEO_DATA_CHUNK_SIZE 0x7E0 -#define VIDEO_DATA_HEADER_SIZE 0x38 -#define RIFF_HEADER_SIZE 0x2C +#define VIDEO_DATA_CHUNK_SIZE 0x7E0 +#define VIDEO_DATA_HEADER_SIZE 0x38 +#define RIFF_HEADER_SIZE 0x2C #define CDXA_TYPE_MASK 0x0E #define CDXA_TYPE_DATA 0x08 @@ -50,20 +48,11 @@ #define STR_MAGIC (0x80010160) typedef struct StrChannel { - - int type; -#define STR_AUDIO 0 -#define STR_VIDEO 1 - /* video parameters */ - int width; - int height; int video_stream_index; + AVPacket tmp_pkt; /* audio parameters */ - int sample_rate; - int channels; - int bits; int audio_stream_index; } StrChannel; @@ -71,37 +60,33 @@ typedef struct StrDemuxContext { /* a STR file can contain up to 32 channels of data */ StrChannel channels[32]; - - /* only decode the first audio and video channels encountered */ - int video_channel; - int audio_channel; - - int64_t pts; - - unsigned char *video_chunk; - AVPacket tmp_pkt; } StrDemuxContext; static const char sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00}; static int str_probe(AVProbeData *p) { - int start; + uint8_t *sector= p->buf; - /* need at least 0x38 bytes to validate */ - if (p->buf_size < 0x38) + if (p->buf_size < RAW_CD_SECTOR_SIZE) return 0; if ((AV_RL32(&p->buf[0]) == RIFF_TAG) && (AV_RL32(&p->buf[8]) == CDXA_TAG)) { /* RIFF header seen; skip 0x2C bytes */ - start = RIFF_HEADER_SIZE; - } else - start = 0; + sector += RIFF_HEADER_SIZE; + } /* look for CD sync header (00, 0xFF x 10, 00) */ - if (memcmp(p->buf+start,sync_header,sizeof(sync_header))) + if (memcmp(sector,sync_header,sizeof(sync_header))) + return 0; + + if(sector[0x11] >= 32) + return 0; + if( (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_VIDEO + && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_AUDIO + && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_DATA) return 0; /* MPEG files (like those ripped from VCDs) can also look like this; @@ -109,36 +94,14 @@ static int str_probe(AVProbeData *p) return 50; } -#if 0 -static void dump(unsigned char *buf,size_t len) -{ - int i; - for(i=0;i<len;i++) { - if ((i&15)==0) av_log(NULL, AV_LOG_DEBUG, "%04x ",i); - av_log(NULL, AV_LOG_DEBUG, "%02x ",buf[i]); - if ((i&15)==15) av_log(NULL, AV_LOG_DEBUG, "\n"); - } - av_log(NULL, AV_LOG_DEBUG, "\n"); -} -#endif - static int str_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = s->pb; StrDemuxContext *str = s->priv_data; - AVStream *st; unsigned char sector[RAW_CD_SECTOR_SIZE]; int start; int i; - int channel; - - /* initialize context members */ - str->pts = 0; - str->audio_channel = -1; /* assume to audio or video */ - str->video_channel = -1; - str->video_chunk = NULL; - /* skip over any RIFF header */ if (get_buffer(pb, sector, RIFF_HEADER_SIZE) != RIFF_HEADER_SIZE) @@ -150,98 +113,12 @@ static int str_read_header(AVFormatContext *s, url_fseek(pb, start, SEEK_SET); - /* check through the first 32 sectors for individual channels */ - for (i = 0; i < 32; i++) { - if (get_buffer(pb, sector, RAW_CD_SECTOR_SIZE) != RAW_CD_SECTOR_SIZE) - return AVERROR(EIO); - -//printf("%02x %02x %02x %02x\n",sector[0x10],sector[0x11],sector[0x12],sector[0x13]); - - channel = sector[0x11]; - if (channel >= 32) - return AVERROR_INVALIDDATA; - - switch (sector[0x12] & CDXA_TYPE_MASK) { - - case CDXA_TYPE_DATA: - case CDXA_TYPE_VIDEO: - /* check if this channel gets to be the dominant video channel */ - if (str->video_channel == -1) { - /* qualify the magic number */ - if (AV_RL32(§or[0x18]) != STR_MAGIC) - break; - str->video_channel = channel; - str->channels[channel].type = STR_VIDEO; - str->channels[channel].width = AV_RL16(§or[0x28]); - str->channels[channel].height = AV_RL16(§or[0x2A]); - - /* allocate a new AVStream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 64, 1, 15); - - str->channels[channel].video_stream_index = st->index; - - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MDEC; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = str->channels[channel].width; - st->codec->height = str->channels[channel].height; - } - break; - - case CDXA_TYPE_AUDIO: - /* check if this channel gets to be the dominant audio channel */ - if (str->audio_channel == -1) { - int fmt; - str->audio_channel = channel; - str->channels[channel].type = STR_AUDIO; - str->channels[channel].channels = - (sector[0x13] & 0x01) ? 2 : 1; - str->channels[channel].sample_rate = - (sector[0x13] & 0x04) ? 18900 : 37800; - str->channels[channel].bits = - (sector[0x13] & 0x10) ? 8 : 4; - - /* allocate a new AVStream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 64, 128, str->channels[channel].sample_rate); - - str->channels[channel].audio_stream_index = st->index; - - fmt = sector[0x13]; - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_XA; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->channels = (fmt&1)?2:1; - st->codec->sample_rate = (fmt&4)?18900:37800; - // st->codec->bit_rate = 0; //FIXME; - st->codec->block_align = 128; - } - break; - - default: - /* ignore */ - break; - } + for(i=0; i<32; i++){ + str->channels[i].video_stream_index= + str->channels[i].audio_stream_index= -1; } -if (str->video_channel != -1) - av_log (s, AV_LOG_DEBUG, " video channel = %d, %d x %d %d\n", str->video_channel, - str->channels[str->video_channel].width, - str->channels[str->video_channel].height,str->channels[str->video_channel].video_stream_index); -if (str->audio_channel != -1) - av_log (s, AV_LOG_DEBUG, " audio channel = %d, %d Hz, %d channels, %d bits/sample %d\n", - str->audio_channel, - str->channels[str->audio_channel].sample_rate, - str->channels[str->audio_channel].channels, - str->channels[str->audio_channel].bits,str->channels[str->audio_channel].audio_stream_index); - - /* back to the start */ - url_fseek(pb, start, SEEK_SET); + s->ctx_flags |= AVFMTCTX_NOHEADER; return 0; } @@ -254,6 +131,7 @@ static int str_read_packet(AVFormatContext *s, unsigned char sector[RAW_CD_SECTOR_SIZE]; int channel; AVPacket *pkt; + AVStream *st; while (1) { @@ -268,40 +146,59 @@ static int str_read_packet(AVFormatContext *s, case CDXA_TYPE_DATA: case CDXA_TYPE_VIDEO: - /* check if this the video channel we care about */ - if (channel == str->video_channel) { + { int current_sector = AV_RL16(§or[0x1C]); int sector_count = AV_RL16(§or[0x1E]); int frame_size = AV_RL32(§or[0x24]); - int bytes_to_copy; -// printf("%d %d %d\n",current_sector,sector_count,frame_size); + + if(!( frame_size>=0 + && current_sector < sector_count + && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){ + av_log(s, AV_LOG_ERROR, "Invalid parameters %d %d %d\n", current_sector, sector_count, frame_size); + break; + } + + if(str->channels[channel].video_stream_index < 0){ + /* allocate a new AVStream */ + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + av_set_pts_info(st, 64, 1, 15); + + str->channels[channel].video_stream_index = st->index; + + st->codec->codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_id = CODEC_ID_MDEC; + st->codec->codec_tag = 0; /* no fourcc */ + st->codec->width = AV_RL16(§or[0x28]); + st->codec->height = AV_RL16(§or[0x2A]); + } + /* if this is the first sector of the frame, allocate a pkt */ - pkt = &str->tmp_pkt; - if (current_sector == 0) { - if (av_new_packet(pkt, frame_size)) + pkt = &str->channels[channel].tmp_pkt; + + if(pkt->size != sector_count*VIDEO_DATA_CHUNK_SIZE){ + if(pkt->data) + av_log(s, AV_LOG_ERROR, "missmatching sector_count\n"); + av_free_packet(pkt); + if (av_new_packet(pkt, sector_count*VIDEO_DATA_CHUNK_SIZE)) return AVERROR(EIO); pkt->pos= url_ftell(pb) - RAW_CD_SECTOR_SIZE; pkt->stream_index = str->channels[channel].video_stream_index; - // pkt->pts = str->pts; - - /* if there is no audio, adjust the pts after every video - * frame; assume 15 fps */ - if (str->audio_channel != -1) - str->pts += (90000 / 15); } - /* load all the constituent chunks in the video packet */ - bytes_to_copy = frame_size - current_sector*VIDEO_DATA_CHUNK_SIZE; - if (bytes_to_copy>0) { - if (bytes_to_copy>VIDEO_DATA_CHUNK_SIZE) bytes_to_copy=VIDEO_DATA_CHUNK_SIZE; - memcpy(pkt->data + current_sector*VIDEO_DATA_CHUNK_SIZE, - sector + VIDEO_DATA_HEADER_SIZE, bytes_to_copy); - } + memcpy(pkt->data + current_sector*VIDEO_DATA_CHUNK_SIZE, + sector + VIDEO_DATA_HEADER_SIZE, + VIDEO_DATA_CHUNK_SIZE); + if (current_sector == sector_count-1) { + pkt->size= frame_size; *ret_pkt = *pkt; + pkt->data= NULL; + pkt->size= -1; return 0; } @@ -309,29 +206,37 @@ static int str_read_packet(AVFormatContext *s, break; case CDXA_TYPE_AUDIO: -#ifdef PRINTSTUFF -printf (" dropping audio sector\n"); -#endif -#if 1 - /* check if this the video channel we care about */ - if (channel == str->audio_channel) { - pkt = ret_pkt; - if (av_new_packet(pkt, 2304)) - return AVERROR(EIO); - memcpy(pkt->data,sector+24,2304); - - pkt->stream_index = - str->channels[channel].audio_stream_index; - //pkt->pts = str->pts; - return 0; + if(str->channels[channel].audio_stream_index < 0){ + int fmt = sector[0x13]; + /* allocate a new AVStream */ + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + + str->channels[channel].audio_stream_index = st->index; + + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_ADPCM_XA; + st->codec->codec_tag = 0; /* no fourcc */ + st->codec->channels = (fmt&1)?2:1; + st->codec->sample_rate = (fmt&4)?18900:37800; + // st->codec->bit_rate = 0; //FIXME; + st->codec->block_align = 128; + + av_set_pts_info(st, 64, 128, st->codec->sample_rate); } -#endif + pkt = ret_pkt; + if (av_new_packet(pkt, 2304)) + return AVERROR(EIO); + memcpy(pkt->data,sector+24,2304); + + pkt->stream_index = + str->channels[channel].audio_stream_index; + return 0; break; default: + av_log(s, AV_LOG_WARNING, "Unknown sector type %02X\n", sector[0x12]); /* drop the sector and move on */ -#ifdef PRINTSTUFF -printf (" dropping other sector\n"); -#endif break; } @@ -343,8 +248,11 @@ printf (" dropping other sector\n"); static int str_read_close(AVFormatContext *s) { StrDemuxContext *str = s->priv_data; - - av_free(str->video_chunk); + int i; + for(i=0; i<32; i++){ + if(str->channels[i].tmp_pkt.data) + av_free_packet(&str->channels[i].tmp_pkt); + } return 0; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/raw.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/raw.c @@ -56,6 +56,11 @@ static int roq_write_header(struct AVFormatContext *s) return 0; } +static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt) +{ + return 0; +} + static int raw_write_packet(struct AVFormatContext *s, AVPacket *pkt) { put_buffer(s->pb, pkt->data, pkt->size); @@ -152,6 +157,30 @@ static int raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt) return ret; } +static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int packet_size, ret, width, height; + AVStream *st = s->streams[0]; + + width = st->codec->width; + height = st->codec->height; + + packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); + if (packet_size < 0) + return -1; + + ret= av_get_packet(s->pb, pkt, packet_size); + pkt->pts= + pkt->dts= pkt->pos / packet_size; + + pkt->stream_index = 0; + if (ret != packet_size) { + return AVERROR(EIO); + } else { + return 0; + } +} + // http://www.artificis.hu/files/texts/ingenient.txt static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt) { @@ -318,6 +347,50 @@ static int mpeg4video_probe(AVProbeData *probe_packet) return 0; } +static int h264_probe(AVProbeData *p) +{ + uint32_t code= -1; + int sps=0, pps=0, idr=0, res=0; + int i; + + for(i=0; i<p->buf_size; i++){ + code = (code<<8) + p->buf[i]; + if ((code & 0xffffff00) == 0x100) { + int ref_idc= (code>>5)&3; + int type = code & 0x1F; + static const int8_t ref_zero[32]={ + 2, 0, 0, 0, 0,-1, 1,-1, + -1, 1, 1, 1, 1,-1, 2, 2, + 2, 2, 2, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2 + }; + + if(code & 0x80) //forbidden bit + return 0; + + if(ref_zero[type] == 1 && ref_idc) + return 0; + if(ref_zero[type] ==-1 && !ref_idc) + return 0; + if(ref_zero[type] == 2) + res++; + + switch(type){ + case 5: idr++; break; + case 7: + if(p->buf[i+2]&0x0F) + return 0; + sps++; + break; + case 8: pps++; break; + } + } + } + if(sps && pps && idr && res<(sps+pps+idr)) + return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg + return 0; +} + static int h263_probe(AVProbeData *p) { int code; @@ -424,56 +497,20 @@ static int flac_probe(AVProbeData *p) else return AVPROBE_SCORE_MAX / 2; } -AVInputFormat shorten_demuxer = { - "shn", - NULL_IF_CONFIG_SMALL("raw Shorten"), - 0, - NULL, - audio_read_header, - raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "shn", - .value = CODEC_ID_SHORTEN, -}; -AVInputFormat mlp_demuxer = { - "mlp", - NULL_IF_CONFIG_SMALL("raw MLP"), - 0, - NULL, - audio_read_header, - raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "mlp", - .value = CODEC_ID_MLP, -}; +/* Note: Do not forget to add new entries to the Makefile as well. */ -AVInputFormat flac_demuxer = { - "flac", - NULL_IF_CONFIG_SMALL("raw FLAC"), +AVInputFormat aac_demuxer = { + "aac", + NULL_IF_CONFIG_SMALL("ADTS AAC"), 0, - flac_probe, + NULL, audio_read_header, raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, - .extensions = "flac", - .value = CODEC_ID_FLAC, -}; - -#ifdef CONFIG_MUXERS -AVOutputFormat flac_muxer = { - "flac", - NULL_IF_CONFIG_SMALL("raw FLAC"), - "audio/x-flac", - "flac", - 0, - CODEC_ID_FLAC, - CODEC_ID_NONE, - flac_write_header, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, + .extensions = "aac", + .value = CODEC_ID_AAC, }; -#endif //CONFIG_MUXERS #ifdef CONFIG_AC3_DEMUXER AVInputFormat ac3_demuxer = { @@ -502,20 +539,6 @@ AVOutputFormat ac3_muxer = { raw_write_packet, .flags= AVFMT_NOTIMESTAMPS, }; - -AVOutputFormat dts_muxer = { - "dts", - NULL_IF_CONFIG_SMALL("raw DTS"), - "audio/x-dca", - "dts", - 0, - CODEC_ID_DTS, - CODEC_ID_NONE, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; - #endif //CONFIG_MUXERS AVInputFormat dirac_demuxer = { @@ -556,18 +579,48 @@ AVInputFormat dts_demuxer = { .value = CODEC_ID_DTS, }; -AVInputFormat aac_demuxer = { - "aac", - NULL_IF_CONFIG_SMALL("ADTS AAC"), +#ifdef CONFIG_MUXERS +AVOutputFormat dts_muxer = { + "dts", + NULL_IF_CONFIG_SMALL("raw DTS"), + "audio/x-dca", + "dts", 0, + CODEC_ID_DTS, + CODEC_ID_NONE, NULL, + raw_write_packet, + .flags= AVFMT_NOTIMESTAMPS, +}; +#endif + +AVInputFormat flac_demuxer = { + "flac", + NULL_IF_CONFIG_SMALL("raw FLAC"), + 0, + flac_probe, audio_read_header, raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, - .extensions = "aac", - .value = CODEC_ID_AAC, + .extensions = "flac", + .value = CODEC_ID_FLAC, }; +#ifdef CONFIG_MUXERS +AVOutputFormat flac_muxer = { + "flac", + NULL_IF_CONFIG_SMALL("raw FLAC"), + "audio/x-flac", + "flac", + 0, + CODEC_ID_FLAC, + CODEC_ID_NONE, + flac_write_header, + raw_write_packet, + .flags= AVFMT_NOTIMESTAMPS, +}; +#endif //CONFIG_MUXERS + AVInputFormat gsm_demuxer = { "gsm", NULL_IF_CONFIG_SMALL("GSM"), @@ -580,21 +633,6 @@ AVInputFormat gsm_demuxer = { .value = CODEC_ID_GSM, }; -#ifdef CONFIG_ROQ_MUXER -AVOutputFormat roq_muxer = -{ - "RoQ", - NULL_IF_CONFIG_SMALL("id RoQ format"), - NULL, - "roq", - 0, - CODEC_ID_ROQ_DPCM, - CODEC_ID_ROQ, - roq_write_header, - raw_write_packet, -}; -#endif //CONFIG_ROQ_MUXER - AVInputFormat h261_demuxer = { "h261", NULL_IF_CONFIG_SMALL("raw H.261"), @@ -649,6 +687,45 @@ AVOutputFormat h263_muxer = { }; #endif //CONFIG_MUXERS +AVInputFormat h264_demuxer = { + "h264", + NULL_IF_CONFIG_SMALL("raw H.264 video format"), + 0, + h264_probe, + video_read_header, + raw_read_partial_packet, + .flags= AVFMT_GENERIC_INDEX, + .extensions = "h26l,h264,264", //FIXME remove after writing mpeg4_probe + .value = CODEC_ID_H264, +}; + +#ifdef CONFIG_MUXERS +AVOutputFormat h264_muxer = { + "h264", + NULL_IF_CONFIG_SMALL("raw H.264 video format"), + NULL, + "h264", + 0, + CODEC_ID_NONE, + CODEC_ID_H264, + NULL, + raw_write_packet, + .flags= AVFMT_NOTIMESTAMPS, +}; +#endif //CONFIG_MUXERS + +AVInputFormat ingenient_demuxer = { + "ingenient", + NULL_IF_CONFIG_SMALL("Ingenient MJPEG"), + 0, + NULL, + video_read_header, + ingenient_read_packet, + .flags= AVFMT_GENERIC_INDEX, + .extensions = "cgi", // FIXME + .value = CODEC_ID_MJPEG, +}; + AVInputFormat m4v_demuxer = { "m4v", NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"), @@ -676,42 +753,43 @@ AVOutputFormat m4v_muxer = { }; #endif //CONFIG_MUXERS -AVInputFormat h264_demuxer = { - "h264", - NULL_IF_CONFIG_SMALL("raw H.264 video format"), +AVInputFormat mjpeg_demuxer = { + "mjpeg", + NULL_IF_CONFIG_SMALL("MJPEG video"), 0, - NULL /*mpegvideo_probe*/, + NULL, video_read_header, raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, - .extensions = "h26l,h264,264", //FIXME remove after writing mpeg4_probe - .value = CODEC_ID_H264, + .extensions = "mjpg,mjpeg", + .value = CODEC_ID_MJPEG, }; #ifdef CONFIG_MUXERS -AVOutputFormat h264_muxer = { - "h264", - NULL_IF_CONFIG_SMALL("raw H.264 video format"), - NULL, - "h264", +AVOutputFormat mjpeg_muxer = { + "mjpeg", + NULL_IF_CONFIG_SMALL("MJPEG video"), + "video/x-mjpeg", + "mjpg,mjpeg", 0, CODEC_ID_NONE, - CODEC_ID_H264, + CODEC_ID_MJPEG, NULL, raw_write_packet, .flags= AVFMT_NOTIMESTAMPS, }; #endif //CONFIG_MUXERS -AVInputFormat mpegvideo_demuxer = { - "mpegvideo", - NULL_IF_CONFIG_SMALL("MPEG video"), +AVInputFormat mlp_demuxer = { + "mlp", + NULL_IF_CONFIG_SMALL("raw MLP"), 0, - mpegvideo_probe, - video_read_header, + NULL, + audio_read_header, raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_MPEG1VIDEO, + .extensions = "mlp", + .value = CODEC_ID_MLP, }; #ifdef CONFIG_MUXERS @@ -744,45 +822,90 @@ AVOutputFormat mpeg2video_muxer = { }; #endif //CONFIG_MUXERS -AVInputFormat mjpeg_demuxer = { - "mjpeg", - NULL_IF_CONFIG_SMALL("MJPEG video"), +AVInputFormat mpegvideo_demuxer = { + "mpegvideo", + NULL_IF_CONFIG_SMALL("MPEG video"), 0, - NULL, + mpegvideo_probe, video_read_header, raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, - .extensions = "mjpg,mjpeg", - .value = CODEC_ID_MJPEG, + .value = CODEC_ID_MPEG1VIDEO, }; -AVInputFormat ingenient_demuxer = { - "ingenient", - NULL_IF_CONFIG_SMALL("Ingenient MJPEG"), +#ifdef CONFIG_MUXERS +AVOutputFormat null_muxer = { + "null", + NULL_IF_CONFIG_SMALL("null video format"), + NULL, + NULL, 0, +#ifdef WORDS_BIGENDIAN + CODEC_ID_PCM_S16BE, +#else + CODEC_ID_PCM_S16LE, +#endif + CODEC_ID_RAWVIDEO, NULL, - video_read_header, - ingenient_read_packet, + null_write_packet, + .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE | AVFMT_NOTIMESTAMPS, +}; +#endif //CONFIG_MUXERS + +AVInputFormat rawvideo_demuxer = { + "rawvideo", + NULL_IF_CONFIG_SMALL("raw video format"), + 0, + NULL, + raw_read_header, + rawvideo_read_packet, .flags= AVFMT_GENERIC_INDEX, - .extensions = "cgi", // FIXME - .value = CODEC_ID_MJPEG, + .extensions = "yuv,cif,qcif,rgb", + .value = CODEC_ID_RAWVIDEO, }; #ifdef CONFIG_MUXERS -AVOutputFormat mjpeg_muxer = { - "mjpeg", - NULL_IF_CONFIG_SMALL("MJPEG video"), - "video/x-mjpeg", - "mjpg,mjpeg", +AVOutputFormat rawvideo_muxer = { + "rawvideo", + NULL_IF_CONFIG_SMALL("raw video format"), + NULL, + "yuv,rgb", 0, CODEC_ID_NONE, - CODEC_ID_MJPEG, + CODEC_ID_RAWVIDEO, NULL, raw_write_packet, .flags= AVFMT_NOTIMESTAMPS, }; #endif //CONFIG_MUXERS +#ifdef CONFIG_ROQ_MUXER +AVOutputFormat roq_muxer = +{ + "RoQ", + NULL_IF_CONFIG_SMALL("id RoQ format"), + NULL, + "roq", + 0, + CODEC_ID_ROQ_DPCM, + CODEC_ID_ROQ, + roq_write_header, + raw_write_packet, +}; +#endif //CONFIG_ROQ_MUXER + +AVInputFormat shorten_demuxer = { + "shn", + NULL_IF_CONFIG_SMALL("raw Shorten"), + 0, + NULL, + audio_read_header, + raw_read_partial_packet, + .flags= AVFMT_GENERIC_INDEX, + .extensions = "shn", + .value = CODEC_ID_SHORTEN, +}; + AVInputFormat vc1_demuxer = { "vc1", NULL_IF_CONFIG_SMALL("raw VC-1"), @@ -849,101 +972,26 @@ AVOutputFormat pcm_ ## name ## _muxer = {\ #endif -PCMDEF(s16le, "pcm signed 16 bit little endian format", - LE_DEF("sw"), CODEC_ID_PCM_S16LE) - -PCMDEF(s16be, "pcm signed 16 bit big endian format", +PCMDEF(s16be, "PCM signed 16 bit big-endian format", BE_DEF("sw"), CODEC_ID_PCM_S16BE) -PCMDEF(u16le, "pcm unsigned 16 bit little endian format", - LE_DEF("uw"), CODEC_ID_PCM_U16LE) +PCMDEF(s16le, "PCM signed 16 bit little-endian format", + LE_DEF("sw"), CODEC_ID_PCM_S16LE) -PCMDEF(u16be, "pcm unsigned 16 bit big endian format", +PCMDEF(s8, "PCM signed 8 bit format", + "sb", CODEC_ID_PCM_S8) + +PCMDEF(u16be, "PCM unsigned 16 bit big-endian format", BE_DEF("uw"), CODEC_ID_PCM_U16BE) -PCMDEF(s8, "pcm signed 8 bit format", - "sb", CODEC_ID_PCM_S8) +PCMDEF(u16le, "PCM unsigned 16 bit little-endian format", + LE_DEF("uw"), CODEC_ID_PCM_U16LE) -PCMDEF(u8, "pcm unsigned 8 bit format", +PCMDEF(u8, "PCM unsigned 8 bit format", "ub", CODEC_ID_PCM_U8) -PCMDEF(mulaw, "pcm mu law format", - "ul", CODEC_ID_PCM_MULAW) - -PCMDEF(alaw, "pcm A law format", +PCMDEF(alaw, "PCM A-law format", "al", CODEC_ID_PCM_ALAW) -static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int packet_size, ret, width, height; - AVStream *st = s->streams[0]; - - width = st->codec->width; - height = st->codec->height; - - packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); - if (packet_size < 0) - return -1; - - ret= av_get_packet(s->pb, pkt, packet_size); - pkt->pts= - pkt->dts= pkt->pos / packet_size; - - pkt->stream_index = 0; - if (ret != packet_size) { - return AVERROR(EIO); - } else { - return 0; - } -} - -AVInputFormat rawvideo_demuxer = { - "rawvideo", - NULL_IF_CONFIG_SMALL("raw video format"), - 0, - NULL, - raw_read_header, - rawvideo_read_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "yuv,cif,qcif,rgb", - .value = CODEC_ID_RAWVIDEO, -}; - -#ifdef CONFIG_MUXERS -AVOutputFormat rawvideo_muxer = { - "rawvideo", - NULL_IF_CONFIG_SMALL("raw video format"), - NULL, - "yuv,rgb", - 0, - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif //CONFIG_MUXERS - -#ifdef CONFIG_MUXERS -static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - return 0; -} - -AVOutputFormat null_muxer = { - "null", - NULL_IF_CONFIG_SMALL("null video format"), - NULL, - NULL, - 0, -#ifdef WORDS_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_RAWVIDEO, - NULL, - null_write_packet, - .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE | AVFMT_NOTIMESTAMPS, -}; -#endif //CONFIG_MUXERS +PCMDEF(mulaw, "PCM mu-law format", + "ul", CODEC_ID_PCM_MULAW) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/riff.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/riff.c @@ -160,6 +160,7 @@ const AVCodecTag codec_bmp_tags[] = { { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') }, { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, { CODEC_ID_CLJR, MKTAG('c', 'l', 'j', 'r') }, + { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, { CODEC_ID_NONE, 0 } }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rmdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rmdec.c @@ -277,7 +277,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) AVStream *st; ByteIOContext *pb = s->pb; unsigned int tag; - int tag_size, i; + int tag_size; unsigned int start_time, duration; char buf[128]; int flags = 0; @@ -297,7 +297,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) for(;;) { if (url_feof(pb)) - goto fail; + return -1; tag = get_le32(pb); tag_size = get_be32(pb); get_be16(pb); @@ -311,7 +311,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) tag_size); #endif if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A')) - goto fail; + return -1; switch(tag) { case MKTAG('P', 'R', 'O', 'P'): /* file header */ @@ -336,7 +336,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) case MKTAG('M', 'D', 'P', 'R'): st = av_new_stream(s, 0); if (!st) - goto fail; + return AVERROR(ENOMEM); st->id = get_be16(pb); get_be32(pb); /* max bit rate */ st->codec->bit_rate = get_be32(pb); /* bit rate */ @@ -369,12 +369,6 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) get_be32(pb); /* next data header */ rm->curpic_num = -1; return 0; - - fail: - for(i=0;i<s->nb_streams;i++) { - av_free(s->streams[i]); - } - return AVERROR(EIO); } static int get_num(ByteIOContext *pb, int *len) diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtp.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtp.c @@ -57,8 +57,8 @@ static const struct {11, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 1}, {12, "QCELP", CODEC_TYPE_AUDIO, CODEC_ID_QCELP, 8000, 1}, {13, "CN", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP2, 90000, -1}, - {14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP3, 90000, -1}, + {14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP2, -1, -1}, + {14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP3, -1, -1}, {15, "G728", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, {16, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 11025, 1}, {17, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 22050, 1}, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtp_mpv.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtp_mpv.c @@ -66,7 +66,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) begin_of_sequence = 1; } - if (r - buf1 < len) { + if (r - buf1 - 4 <= len) { /* The current slice fits in the packet */ if (begin_of_slice == 0) { /* no slice at the beginning of the packet... */ @@ -76,7 +76,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) } r1 = r; } else { - if (r - r1 < max_packet_size - 4) { + if ((r1 - buf1 > 4) && (r - r1 < max_packet_size)) { len = r1 - buf1 - 4; end_of_slice = 1; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtpdec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtpdec.c @@ -250,13 +250,9 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) len = url_close_dyn_buf(pb, &buf); if ((len > 0) && buf) { int result; -#if defined(DEBUG) - printf("sending %d bytes of RR\n", len); -#endif + dprintf(s->ic, "sending %d bytes of RR\n", len); result= url_write(s->rtp_ctx, buf, len); -#if defined(DEBUG) - printf("result from url_write: %d\n", result); -#endif + dprintf(s->ic, "result from url_write: %d\n", result); av_free(buf); } return 0; @@ -282,6 +278,7 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r s->st = st; s->rtp_payload_data = rtp_payload_data; rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp? + av_set_pts_info(s->st, 32, 1, 90000); if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) { s->ts = mpegts_parse_open(s->ic); if (s->ts == NULL) { @@ -299,6 +296,9 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r st->need_parsing = AVSTREAM_PARSE_FULL; break; default: + if (st->codec->codec_type == CODEC_TYPE_AUDIO) { + av_set_pts_info(st, 32, 1, st->codec->sample_rate); + } break; } } @@ -361,31 +361,15 @@ static int rtp_parse_mp4_au(RTPDemuxContext *s, const uint8_t *buf) */ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) { - switch(s->st->codec->codec_id) { - case CODEC_ID_MP2: - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { - int64_t addend; - - int delta_timestamp; - /* XXX: is it really necessary to unify the timestamp base ? */ - /* compute pts from timestamp with received ntp_time */ - delta_timestamp = timestamp - s->last_rtcp_timestamp; - /* convert to 90 kHz without overflow */ - addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14; - addend = (addend * 5625) >> 14; - pkt->pts = addend + delta_timestamp; - } - break; - case CODEC_ID_AAC: - case CODEC_ID_H264: - case CODEC_ID_MPEG4: - pkt->pts = timestamp; - break; - default: - /* no timestamp info yet */ - break; + if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { + int64_t addend; + int delta_timestamp; + + /* compute pts from timestamp with received ntp_time */ + delta_timestamp = timestamp - s->last_rtcp_timestamp; + /* convert to the PTS timebase */ + addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time, s->st->time_base.den, (uint64_t)s->st->time_base.num << 32); + pkt->pts = addend + delta_timestamp; } pkt->stream_index = s->st->index; } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtpenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtpenc.c @@ -81,7 +81,7 @@ static int rtp_write_header(AVFormatContext *s1) } if (st->codec->codec_type == CODEC_TYPE_VIDEO) { /* FIXME: We should round down here... */ - s->max_frames_per_packet = av_rescale_q(s1->max_delay, AV_TIME_BASE_Q, st->codec->time_base); + s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base); } } @@ -120,13 +120,11 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) RTPDemuxContext *s = s1->priv_data; uint32_t rtp_ts; -#if defined(DEBUG) - printf("RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); -#endif + dprintf(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) s->first_rtcp_ntp_time = ntp_time; s->last_rtcp_ntp_time = ntp_time; - rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, AV_TIME_BASE_Q, + rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000}, s1->streams[0]->time_base) + s->base_timestamp; put_byte(s1->pb, (RTP_VERSION << 6)); put_byte(s1->pb, 200); @@ -146,9 +144,7 @@ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m) { RTPDemuxContext *s = s1->priv_data; -#ifdef DEBUG - printf("rtp_send_data size=%d\n", len); -#endif + dprintf(s1, "rtp_send_data size=%d\n", len); /* build the RTP header */ put_byte(s1->pb, (RTP_VERSION << 6)); @@ -301,11 +297,8 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) int size= pkt->size; uint8_t *buf1= pkt->data; -#ifdef DEBUG - printf("%d: write len=%d\n", pkt->stream_index, size); -#endif + dprintf(s1, "%d: write len=%d\n", pkt->stream_index, size); - /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */ rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / RTCP_TX_RATIO_DEN; if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtsp.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/rtsp.c @@ -842,7 +842,6 @@ static void rtsp_close_streams(RTSPState *rt) if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) rtsp_st->dynamic_handler->close(rtsp_st->dynamic_protocol_context); } - av_free(rtsp_st); } av_free(rt->rtsp_streams); } diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/sdp.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/sdp.c @@ -59,7 +59,7 @@ static void sdp_write_header(char *buff, int size, struct sdp_session_level *s) "o=- %d %d IN IPV4 %s\r\n" "t=%d %d\r\n" "s=%s\r\n" - "a=tool:libavformat\r\n", + "a=tool:libavformat " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\r\n", s->sdp_version, s->id, s->version, s->src_addr, s->start_time, s->end_time, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/swf.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/swf.h @@ -67,7 +67,7 @@ typedef struct { int audio_stream_index; offset_t duration_pos; offset_t tag_pos; - + offset_t vframes_pos; int samples_per_frame; int sound_samples; int swf_frame_number; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/swfenc.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/swfenc.c @@ -344,6 +344,7 @@ static int swf_write_video(AVFormatContext *s, /* create a new video object */ put_swf_tag(s, TAG_VIDEOSTREAM); put_le16(pb, VIDEO_ID); + swf->vframes_pos = url_ftell(pb); put_le16(pb, 15000); /* hard flash player limit */ put_le16(pb, enc->width); put_le16(pb, enc->height); @@ -495,6 +496,8 @@ static int swf_write_trailer(AVFormatContext *s) put_le32(pb, file_size); url_fseek(pb, swf->duration_pos, SEEK_SET); put_le16(pb, swf->video_frame_number); + url_fseek(pb, swf->vframes_pos, SEEK_SET); + put_le16(pb, swf->video_frame_number); url_fseek(pb, file_size, SEEK_SET); } return 0; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/tiertexseq.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/tiertexseq.c @@ -285,7 +285,7 @@ static int seq_read_packet(AVFormatContext *s, AVPacket *pkt) return rc; pkt->stream_index = seq->audio_stream_index; - pkt->pts = seq->current_frame_pts++; + seq->current_frame_pts++; seq->audio_buffer_full = 0; return 0; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/utils.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/utils.c @@ -293,6 +293,24 @@ AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){ return av_probe_input_format2(pd, is_opened, &score); } +static int set_codec_from_probe_data(AVStream *st, AVProbeData *pd, int score) +{ + AVInputFormat *fmt; + fmt = av_probe_input_format2(pd, 1, &score); + + if (fmt) { + if (!strcmp(fmt->name, "mp3")) + st->codec->codec_id = CODEC_ID_MP3; + else if (!strcmp(fmt->name, "ac3")) + st->codec->codec_id = CODEC_ID_AC3; + else if (!strcmp(fmt->name, "mpegvideo")) + st->codec->codec_id = CODEC_ID_MPEG2VIDEO; + else if (!strcmp(fmt->name, "h264")) + st->codec->codec_id = CODEC_ID_H264; + } + return !!fmt; +} + /************************************************************/ /* input media file */ @@ -394,9 +412,11 @@ int av_open_input_stream(AVFormatContext **ic_ptr, ic->priv_data = NULL; } - err = ic->iformat->read_header(ic, ap); - if (err < 0) - goto fail; + if (ic->iformat->read_header) { + err = ic->iformat->read_header(ic, ap); + if (err < 0) + goto fail; + } if (pb && !ic->data_offset) ic->data_offset = url_ftell(ic->pb); @@ -405,7 +425,16 @@ int av_open_input_stream(AVFormatContext **ic_ptr, return 0; fail: if (ic) { + int i; av_freep(&ic->priv_data); + for(i=0;i<ic->nb_streams;i++) { + AVStream *st = ic->streams[i]; + if (st) { + av_free(st->priv_data); + av_free(st->codec->extradata); + } + av_free(st); + } } av_free(ic); *ic_ptr = NULL; @@ -495,29 +524,79 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, /*******************************************************/ +static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt){ + AVPacketList *pktl; + AVPacketList **plast_pktl= packet_buffer; + + while(*plast_pktl) plast_pktl= &(*plast_pktl)->next; //FIXME maybe maintain pointer to the last? + + pktl = av_mallocz(sizeof(AVPacketList)); + if (!pktl) + return NULL; + + /* add the packet in the buffered packet list */ + *plast_pktl = pktl; + pktl->pkt= *pkt; + return &pktl->pkt; +} + int av_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret; AVStream *st; - av_init_packet(pkt); - ret= s->iformat->read_packet(s, pkt); - if (ret < 0) - return ret; - st= s->streams[pkt->stream_index]; - switch(st->codec->codec_type){ - case CODEC_TYPE_VIDEO: - if(s->video_codec_id) st->codec->codec_id= s->video_codec_id; - break; - case CODEC_TYPE_AUDIO: - if(s->audio_codec_id) st->codec->codec_id= s->audio_codec_id; - break; - case CODEC_TYPE_SUBTITLE: - if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id; - break; - } + for(;;){ + AVPacketList *pktl = s->raw_packet_buffer; - return ret; + if (pktl) { + *pkt = pktl->pkt; + if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE){ + s->raw_packet_buffer = pktl->next; + av_free(pktl); + return 0; + } + } + + av_init_packet(pkt); + ret= s->iformat->read_packet(s, pkt); + if (ret < 0) + return ret; + st= s->streams[pkt->stream_index]; + + switch(st->codec->codec_type){ + case CODEC_TYPE_VIDEO: + if(s->video_codec_id) st->codec->codec_id= s->video_codec_id; + break; + case CODEC_TYPE_AUDIO: + if(s->audio_codec_id) st->codec->codec_id= s->audio_codec_id; + break; + case CODEC_TYPE_SUBTITLE: + if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id; + break; + } + + if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE) + return ret; + + add_to_pktbuf(&s->raw_packet_buffer, pkt); + + if(st->codec->codec_id == CODEC_ID_PROBE){ + AVProbeData *pd = &st->probe_data; + + pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); + memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); + pd->buf_size += pkt->size; + memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); + + if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ + set_codec_from_probe_data(st, pd, 1); + if(st->codec->codec_id != CODEC_ID_PROBE){ + pd->buf_size=0; + av_freep(&pd->buf); + } + } + } + } } /**********************************************************/ @@ -529,6 +608,9 @@ static int get_audio_frame_size(AVCodecContext *enc, int size) { int frame_size; + if(enc->codec_id == CODEC_ID_VORBIS) + return -1; + if (enc->frame_size <= 1) { int bits_per_sample = av_get_bits_per_sample(enc->codec_id); @@ -613,7 +695,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, AVStream *st= s->streams[stream_index]; AVPacketList *pktl= s->packet_buffer; - if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE) + if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE) return; st->first_dts= dts - st->cur_dts; @@ -716,10 +798,6 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts) presentation_delayed = 1; - if(st->cur_dts == AV_NOPTS_VALUE){ - st->cur_dts = 0; //FIXME maybe set it to 0 during init - } - // av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts, pkt->stream_index, pc); /* interpolate PTS and DTS if they are not present */ if(delay==0 || (delay==1 && pc)){ @@ -736,7 +814,8 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, of the frame we are displaying, i.e. the last I- or P-frame */ if (st->last_IP_duration == 0) st->last_IP_duration = pkt->duration; - st->cur_dts = pkt->dts + st->last_IP_duration; + if(pkt->dts != AV_NOPTS_VALUE) + st->cur_dts = pkt->dts + st->last_IP_duration; st->last_IP_duration = pkt->duration; st->last_IP_pts= pkt->pts; /* cannot compute PTS if not present (we can compute it only @@ -758,7 +837,8 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if(pkt->pts == AV_NOPTS_VALUE) pkt->pts = st->cur_dts; pkt->dts = pkt->pts; - st->cur_dts = pkt->pts + pkt->duration; + if(pkt->pts != AV_NOPTS_VALUE) + st->cur_dts = pkt->pts + pkt->duration; } } @@ -883,11 +963,12 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) st = s->streams[s->cur_pkt.stream_index]; if(s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n", + av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, flags=%d\n", s->cur_pkt.stream_index, s->cur_pkt.pts, s->cur_pkt.dts, - s->cur_pkt.size); + s->cur_pkt.size, + s->cur_pkt.flags); s->cur_st = st; s->cur_ptr = s->cur_pkt.data; @@ -908,31 +989,16 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) } } if(s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n", + av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, flags=%d\n", pkt->stream_index, pkt->pts, pkt->dts, - pkt->size); + pkt->size, + pkt->flags); return 0; } -static AVPacket *add_to_pktbuf(AVFormatContext *s, AVPacket *pkt){ - AVPacketList *pktl= s->packet_buffer; - AVPacketList **plast_pktl= &s->packet_buffer; - - while(*plast_pktl) plast_pktl= &(*plast_pktl)->next; //FIXME maybe maintain pointer to the last? - - pktl = av_mallocz(sizeof(AVPacketList)); - if (!pktl) - return NULL; - - /* add the packet in the buffered packet list */ - *plast_pktl = pktl; - pktl->pkt= *pkt; - return &pktl->pkt; -} - int av_read_frame(AVFormatContext *s, AVPacket *pkt) { AVPacketList *pktl; @@ -977,7 +1043,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) return ret; } - if(av_dup_packet(add_to_pktbuf(s, pkt)) < 0) + if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt)) < 0) return AVERROR(ENOMEM); }else{ assert(!s->packet_buffer); @@ -1717,6 +1783,10 @@ static int has_codec_parameters(AVCodecContext *enc) switch(enc->codec_type) { case CODEC_TYPE_AUDIO: val = enc->sample_rate && enc->channels; + if(!enc->frame_size && + (enc->codec_id == CODEC_ID_VORBIS || + enc->codec_id == CODEC_ID_AAC)) + return 0; break; case CODEC_TYPE_VIDEO: val = enc->width && enc->pix_fmt != PIX_FMT_NONE; @@ -1767,20 +1837,6 @@ static int try_decode_frame(AVStream *st, const uint8_t *data, int size) return ret; } -static int set_codec_from_probe_data(AVStream *st, AVProbeData *pd, int score) -{ - AVInputFormat *fmt; - fmt = av_probe_input_format2(pd, 1, &score); - - if (fmt) { - if (strncmp(fmt->name, "mp3", 3) == 0) - st->codec->codec_id = CODEC_ID_MP3; - else if (strncmp(fmt->name, "ac3", 3) == 0) - st->codec->codec_id = CODEC_ID_AC3; - } - return !!fmt; -} - unsigned int codec_get_tag(const AVCodecTag *tags, int id) { while (tags->id != CODEC_ID_NONE) { @@ -1886,8 +1942,6 @@ int av_find_stream_info(AVFormatContext *ic) offset_t old_offset = url_ftell(ic->pb); int64_t codec_info_duration[MAX_STREAMS]={0}; int codec_info_nb_frames[MAX_STREAMS]={0}; - AVProbeData probe_data[MAX_STREAMS]; - int codec_identified[MAX_STREAMS]={0}; duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error)); if (!duration_error) return AVERROR(ENOMEM); @@ -1913,7 +1967,6 @@ int av_find_stream_info(AVFormatContext *ic) last_dts[i]= AV_NOPTS_VALUE; } - memset(probe_data, 0, sizeof(probe_data)); count = 0; read_size = 0; for(;;) { @@ -1966,12 +2019,11 @@ int av_find_stream_info(AVFormatContext *ic) break; } - pkt= add_to_pktbuf(ic, &pkt1); - if(av_dup_packet(pkt) < 0) - { - av_free(duration_error); + pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1); + if(av_dup_packet(pkt) < 0) { + av_free(duration_error); return AVERROR(ENOMEM); - } + } read_size += pkt->size; @@ -2003,14 +2055,6 @@ int av_find_stream_info(AVFormatContext *ic) } if(last == AV_NOPTS_VALUE || duration_count[index]<=1) last_dts[pkt->stream_index]= pkt->dts; - - if (st->codec->codec_id == CODEC_ID_NONE) { - AVProbeData *pd = &(probe_data[st->index]); - pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); - memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); - pd->buf_size += pkt->size; - memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); - } } if(st->parser && st->parser->parser->split && !st->codec->extradata){ int i= st->parser->parser->split(st->codec, pkt->data, pkt->size); @@ -2090,12 +2134,6 @@ int av_find_stream_info(AVFormatContext *ic) } } }else if(st->codec->codec_type == CODEC_TYPE_AUDIO) { - if (st->codec->codec_id == CODEC_ID_NONE && probe_data[st->index].buf_size > 0) { - codec_identified[st->index] = set_codec_from_probe_data(st, &(probe_data[st->index]), 1); - if (codec_identified[st->index]) { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - } if(!st->codec->bits_per_sample) st->codec->bits_per_sample= av_get_bits_per_sample(st->codec->codec_id); } @@ -2103,24 +2141,6 @@ int av_find_stream_info(AVFormatContext *ic) av_estimate_timings(ic, old_offset); - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (codec_identified[st->index]) - break; - } - //FIXME this is a mess - if(i!=ic->nb_streams){ - av_read_frame_flush(ic); - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (codec_identified[st->index]) { - av_seek_frame(ic, st->index, 0.0, 0); - } - st->cur_dts= st->first_dts; - } - url_fseek(ic->pb, ic->data_offset, SEEK_SET); - } - compute_chapters_end(ic); #if 0 @@ -2149,9 +2169,6 @@ int av_find_stream_info(AVFormatContext *ic) #endif av_free(duration_error); - for(i=0;i<MAX_STREAMS;i++){ - av_freep(&(probe_data[i].buf)); - } return ret; } @@ -2197,6 +2214,7 @@ void av_close_input_stream(AVFormatContext *s) av_free(st->codec->extradata); av_free(st->codec); av_free(st->filename); + av_free(st->priv_data); av_free(st); } for(i=s->nb_programs-1; i>=0; i--) { @@ -2245,7 +2263,11 @@ AVStream *av_new_stream(AVFormatContext *s, int id) st->id = id; st->start_time = AV_NOPTS_VALUE; st->duration = AV_NOPTS_VALUE; - st->cur_dts = AV_NOPTS_VALUE; + /* we set the current DTS to 0 so that formats without any timestamps + but durations get some timestamps, formats with some unknown + timestamps have their first few packets buffered and the + timestamps corrected before they are returned to the user */ + st->cur_dts = 0; st->first_dts = AV_NOPTS_VALUE; /* default pts setting is MPEG-like */ @@ -2435,6 +2457,9 @@ static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){ } } + if(pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay==0) + pkt->pts= pkt->dts; + //XXX/FIXME this is a temporary hack until all encoders output pts if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay){ pkt->dts= @@ -2454,11 +2479,11 @@ static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){ } if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){ - av_log(NULL, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64"\n", st->cur_dts, pkt->dts); + av_log(st->codec, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64"\n", st->cur_dts, pkt->dts); return -1; } if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){ - av_log(NULL, AV_LOG_ERROR, "error, pts < dts\n"); + av_log(st->codec, AV_LOG_ERROR, "error, pts < dts\n"); return -1; } @@ -3129,9 +3154,13 @@ void url_split(char *proto, int proto_size, void av_set_pts_info(AVStream *s, int pts_wrap_bits, int pts_num, int pts_den) { + unsigned int gcd= ff_gcd(pts_num, pts_den); s->pts_wrap_bits = pts_wrap_bits; - s->time_base.num = pts_num; - s->time_base.den = pts_den; + s->time_base.num = pts_num/gcd; + s->time_base.den = pts_den/gcd; + + if(gcd>1) + av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, gcd); } /* fraction handling */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/yuv4mpeg.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavformat/yuv4mpeg.c @@ -29,6 +29,7 @@ struct frame_attributes { int top_field_first; }; +#ifdef CONFIG_YUV4MPEGPIPE_MUXER static int yuv4_generate_header(AVFormatContext *s, char* buf) { AVStream *st; @@ -166,7 +167,6 @@ static int yuv4_write_header(AVFormatContext *s) return 0; } -#ifdef CONFIG_YUV4MPEGPIPE_MUXER AVOutputFormat yuv4mpegpipe_muxer = { "yuv4mpegpipe", NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"), diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/bswap.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/bswap.h @@ -40,6 +40,8 @@ static av_always_inline av_const uint16_t bswap_16(uint16_t x) asm("rorw $8, %0" : "+r"(x)); #elif defined(ARCH_SH4) asm("swap.b %0,%0" : "=r"(x) : "0"(x)); +#elif defined(HAVE_ARMV6) + asm("rev16 %0, %0" : "+r"(x)); #else x= (x>>8) | (x<<8); #endif @@ -62,7 +64,9 @@ static av_always_inline av_const uint32_t bswap_32(uint32_t x) "swap.w %0,%0\n" "swap.b %0,%0\n" : "=r"(x) : "0"(x)); -#elif defined(ARCH_ARM) +#elif defined(HAVE_ARMV6) + asm("rev %0, %0" : "+r"(x)); +#elif defined(ARCH_ARMV4L) uint32_t t; asm ("eor %1, %0, %0, ror #16 \n\t" "bic %1, %1, #0xFF0000 \n\t" diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/common.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/common.h @@ -225,6 +225,20 @@ static inline av_const int16_t av_clip_int16(int a) else return a; } +/** + * clip a float value into the amin-amax range + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const float av_clipf(float a, float amin, float amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + /* math */ int64_t av_const ff_gcd(int64_t a, int64_t b); diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/internal.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/internal.h @@ -50,11 +50,13 @@ #endif #endif +#ifdef HAVE_ALTIVEC #ifdef HAVE_ALTIVEC_VECTOR_BRACES #define AVV(x...) {x} #else #define AVV(x...) (x) #endif +#endif #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -152,6 +154,13 @@ extern const uint32_t ff_inverse[256]; );\ ret;\ }) +#elif defined(HAVE_ARMV6) +static inline av_const int FASTDIV(int a, int b) +{ + int r; + asm volatile("smmul %0, %1, %2" : "=r"(r) : "r"(a), "r"(ff_inverse[b])); + return r; +} #elif defined(ARCH_ARMV4L) # define FASTDIV(a,b) \ ({\ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/intreadwrite.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/intreadwrite.h @@ -37,7 +37,17 @@ struct unaligned_16 { uint16_t l; } __attribute__((packed)); #define AV_WN32(a, b) (((struct unaligned_32 *) (a))->l) = (b) #define AV_WN64(a, b) (((struct unaligned_64 *) (a))->l) = (b) -#else /* __GNUC__ */ +#elif defined(__DECC) + +#define AV_RN16(a) (*((const __unaligned uint16_t*)(a))) +#define AV_RN32(a) (*((const __unaligned uint32_t*)(a))) +#define AV_RN64(a) (*((const __unaligned uint64_t*)(a))) + +#define AV_WN16(a, b) *((__unaligned uint16_t*)(a)) = (b) +#define AV_WN32(a, b) *((__unaligned uint32_t*)(a)) = (b) +#define AV_WN64(a, b) *((__unaligned uint64_t*)(a)) = (b) + +#else #define AV_RN16(a) (*((const uint16_t*)(a))) #define AV_RN32(a) (*((const uint32_t*)(a))) @@ -63,12 +73,36 @@ struct unaligned_16 { uint16_t l; } __attribute__((packed)); # define AV_RL16(x) bswap_16(AV_RN16(x)) # define AV_WL16(p, d) AV_WN16(p, bswap_16(d)) + +# define AV_RB32(x) AV_RN32(x) +# define AV_WB32(p, d) AV_WN32(p, d) + +# define AV_RL32(x) bswap_32(AV_RN32(x)) +# define AV_WL32(p, d) AV_WN32(p, bswap_32(d)) + +# define AV_RB64(x) AV_RN64(x) +# define AV_WB64(p, d) AV_WN64(p, d) + +# define AV_RL64(x) bswap_64(AV_RN64(x)) +# define AV_WL64(p, d) AV_WN64(p, bswap_64(d)) # else /* WORDS_BIGENDIAN */ # define AV_RB16(x) bswap_16(AV_RN16(x)) # define AV_WB16(p, d) AV_WN16(p, bswap_16(d)) # define AV_RL16(x) AV_RN16(x) # define AV_WL16(p, d) AV_WN16(p, d) + +# define AV_RB32(x) bswap_32(AV_RN32(x)) +# define AV_WB32(p, d) AV_WN32(p, bswap_32(d)) + +# define AV_RL32(x) AV_RN32(x) +# define AV_WL32(p, d) AV_WN32(p, d) + +# define AV_RB64(x) bswap_64(AV_RN64(x)) +# define AV_WB64(p, d) AV_WN64(p, bswap_64(d)) + +# define AV_RL64(x) AV_RN64(x) +# define AV_WL64(p, d) AV_WN64(p, d) # endif #else /* HAVE_FAST_UNALIGNED */ #define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1]) @@ -81,39 +115,7 @@ struct unaligned_16 { uint16_t l; } __attribute__((packed)); #define AV_WL16(p, d) do { \ ((uint8_t*)(p))[0] = (d); \ ((uint8_t*)(p))[1] = (d)>>8; } while(0) -#endif - -#define AV_RB24(x) ((((const uint8_t*)(x))[0] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[2]) -#define AV_WB24(p, d) do { \ - ((uint8_t*)(p))[2] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[0] = (d)>>16; } while(0) -#define AV_RL24(x) ((((const uint8_t*)(x))[2] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) -#define AV_WL24(p, d) do { \ - ((uint8_t*)(p))[0] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[2] = (d)>>16; } while(0) - -#ifdef HAVE_FAST_UNALIGNED -# ifdef WORDS_BIGENDIAN -# define AV_RB32(x) AV_RN32(x) -# define AV_WB32(p, d) AV_WN32(p, d) - -# define AV_RL32(x) bswap_32(AV_RN32(x)) -# define AV_WL32(p, d) AV_WN32(p, bswap_32(d)) -# else /* WORDS_BIGENDIAN */ -# define AV_RB32(x) bswap_32(AV_RN32(x)) -# define AV_WB32(p, d) AV_WN32(p, bswap_32(d)) - -# define AV_RL32(x) AV_RN32(x) -# define AV_WL32(p, d) AV_WN32(p, d) -# endif -#else /* HAVE_FAST_UNALIGNED */ #define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \ (((const uint8_t*)(x))[1] << 16) | \ (((const uint8_t*)(x))[2] << 8) | \ @@ -133,23 +135,7 @@ struct unaligned_16 { uint16_t l; } __attribute__((packed)); ((uint8_t*)(p))[1] = (d)>>8; \ ((uint8_t*)(p))[2] = (d)>>16; \ ((uint8_t*)(p))[3] = (d)>>24; } while(0) -#endif - -#ifdef HAVE_FAST_UNALIGNED -# ifdef WORDS_BIGENDIAN -# define AV_RB64(x) AV_RN64(x) -# define AV_WB64(p, d) AV_WN64(p, d) - -# define AV_RL64(x) bswap_64(AV_RN64(x)) -# define AV_WL64(p, d) AV_WN64(p, bswap_64(d)) -# else /* WORDS_BIGENDIAN */ -# define AV_RB64(x) bswap_64(AV_RN64(x)) -# define AV_WB64(p, d) AV_WN64(p, bswap_64(d)) -# define AV_RL64(x) AV_RN64(x) -# define AV_WL64(p, d) AV_WN64(p, d) -# endif -#else /* HAVE_FAST_UNALIGNED */ #define AV_RB64(x) (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ @@ -185,6 +171,22 @@ struct unaligned_16 { uint16_t l; } __attribute__((packed)); ((uint8_t*)(p))[5] = (d)>>40; \ ((uint8_t*)(p))[6] = (d)>>48; \ ((uint8_t*)(p))[7] = (d)>>56; } while(0) -#endif +#endif /* HAVE_FAST_UNALIGNED */ + +#define AV_RB24(x) ((((const uint8_t*)(x))[0] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[2]) +#define AV_WB24(p, d) do { \ + ((uint8_t*)(p))[2] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[0] = (d)>>16; } while(0) + +#define AV_RL24(x) ((((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#define AV_WL24(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; } while(0) #endif /* FFMPEG_INTREADWRITE_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/log.c b/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/log.c @@ -36,7 +36,7 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) return; #undef fprintf if(print_prefix && avc) { - fprintf(stderr, "[%s @ %p]", avc->item_name(ptr), avc); + fprintf(stderr, "[%s @ %p]", avc->item_name(ptr), ptr); } #define fprintf please_use_av_log diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/x86_cpu.h b/src/plugins/thumbnailffmpeg/ffmpeg/libavutil/x86_cpu.h @@ -68,6 +68,10 @@ typedef int32_t x86_reg; # define HAVE_7REGS 1 #endif +#if defined(ARCH_X86_64) || (defined(ARCH_X86_32) && (defined(HAVE_EBX_AVAILABLE) || defined(HAVE_EBP_AVAILABLE))) +# define HAVE_6REGS 1 +#endif + #if defined(ARCH_X86_64) && defined(PIC) # define BROKEN_RELOCATIONS 1 #endif diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/Makefile b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/Makefile @@ -3,7 +3,7 @@ include $(SUBDIR)../config.mak NAME = swscale FFLIBS = avutil -OBJS = rgb2rgb.o swscale.o +OBJS = rgb2rgb.o swscale.o swscale_avoption.o OBJS-$(ARCH_BFIN) += swscale_bfin.o yuv2rgb_bfin.o OBJS-$(CONFIG_GPL) += yuv2rgb.o diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/internal_bfin.S b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/internal_bfin.S @@ -2,8 +2,8 @@ * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * April 20, 2007 * - * Blackfin Video Color Space Converters Operations - * convert I420 YV12 to RGB in various formats, + * Blackfin video color space converter operations + * convert I420 YV12 to RGB in various formats * * This file is part of FFmpeg. * @@ -24,74 +24,73 @@ /* - YUV420 to RGB565 conversion. This routine takes a YUV 420 planar macroblock - and converts it to RGB565. R:5 bits, G:6 bits, B:5 bits.. packed into shorts +YUV420 to RGB565 conversion. This routine takes a YUV 420 planar macroblock +and converts it to RGB565. R:5 bits, G:6 bits, B:5 bits.. packed into shorts. - The following calculation is used for the conversion: +The following calculation is used for the conversion: - r = clipz((y-oy)*cy + crv*(v-128)) - g = clipz((y-oy)*cy + cgv*(v-128) + cgu*(u-128)) - b = clipz((y-oy)*cy + cbu*(u-128)) + r = clipz((y-oy)*cy + crv*(v-128)) + g = clipz((y-oy)*cy + cgv*(v-128) + cgu*(u-128)) + b = clipz((y-oy)*cy + cbu*(u-128)) - y,u,v are pre scaled by a factor of 4 i.e. left shifted to gain precision. +y,u,v are prescaled by a factor of 4 i.e. left-shifted to gain precision. - New factorization to eliminate the truncation error which was - occuring due to the byteop3p. +New factorization to eliminate the truncation error which was +occurring due to the byteop3p. - 1) use the bytop16m to subtract quad bytes we use this in U8 this - then so the offsets need to be renormalized to 8bits. +1) Use the bytop16m to subtract quad bytes we use this in U8 this + then so the offsets need to be renormalized to 8bits. - 2) scale operands up by a factor of 4 not 8 because Blackfin - multiplies include a shift. +2) Scale operands up by a factor of 4 not 8 because Blackfin + multiplies include a shift. - 3) compute into the accumulators cy*yx0, cy*yx1 +3) Compute into the accumulators cy*yx0, cy*yx1. - 4) compute each of the linear equations - r = clipz((y-oy)*cy + crv*(v-128)) +4) Compute each of the linear equations: + r = clipz((y - oy) * cy + crv * (v - 128)) - g = clipz((y-oy)*cy + cgv*(v-128) + cgu*(u-128)) + g = clipz((y - oy) * cy + cgv * (v - 128) + cgu * (u - 128)) - b = clipz((y-oy)*cy + cbu*(u-128)) + b = clipz((y - oy) * cy + cbu * (u - 128)) - reuse of the accumulators requires that we actually multiply - twice once with addition and the second time with a subtaction. + Reuse of the accumulators requires that we actually multiply + twice once with addition and the second time with a subtraction. - because of this we need to compute the equations in the order R B - then G saving the writes for B in the case of 24/32 bit color - formats. + Because of this we need to compute the equations in the order R B + then G saving the writes for B in the case of 24/32 bit color + formats. - api: yuv2rgb_kind (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, - int dW, uint32_t *coeffs); + API: yuv2rgb_kind (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, + int dW, uint32_t *coeffs); - A B - --- --- - i2 = cb i3 = cr - i1 = coeff i0 = y + A B + --- --- + i2 = cb i3 = cr + i1 = coeff i0 = y - Where coeffs have the following layout in memory. +Where coeffs have the following layout in memory. - uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv; +uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv; - coeffs is a pointer to oy. +coeffs is a pointer to oy. - the {rgb} masks are only utilized by the 565 packing algorithm. Note the data - replication is used to simplify the internal algorithms for the dual mac architecture - of BlackFin. +The {rgb} masks are only utilized by the 565 packing algorithm. Note the data +replication is used to simplify the internal algorithms for the dual Mac +architecture of BlackFin. - All routines are exported with _ff_bfin_ as a symbol prefix +All routines are exported with _ff_bfin_ as a symbol prefix. - rough performance gain compared against -O3: +Rough performance gain compared against -O3: - 2779809/1484290 187.28% - - which translates to ~33c/pel to ~57c/pel for the reference vs 17.5 - c/pel for the optimized implementations. Not sure why there is such a - huge variation on the reference codes on Blackfin I guess it must have - to do with the memory system. +2779809/1484290 187.28% +which translates to ~33c/pel to ~57c/pel for the reference vs 17.5 +c/pel for the optimized implementations. Not sure why there is such a +huge variation on the reference codes on Blackfin I guess it must have +to do with the memory system. */ #define mL3 .text diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/rgb2rgb.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/rgb2rgb.c @@ -1,10 +1,10 @@ /* - * rgb2rgb.c, Software RGB to RGB convertor - * pluralize by Software PAL8 to RGB convertor - * Software YUV to YUV convertor - * Software YUV to RGB convertor - * Written by Nick Kurshev. - * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) + * software RGB to RGB converter + * pluralize by software PAL8 to RGB converter + * software YUV to YUV converter + * software YUV to RGB converter + * Written by Nick Kurshev. + * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) * * This file is part of FFmpeg. * @@ -22,8 +22,8 @@ * along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * the C code (not assembly, mmx, ...) of this file can be used - * under the LGPL license too + * The C code (not assembly, MMX, ...) of this file can be used + * under the LGPL license. */ #include <inttypes.h> #include "config.h" @@ -33,7 +33,7 @@ #include "swscale.h" #include "swscale_internal.h" -#define FAST_BGR2YV12 // use 7 bit coeffs instead of 15bit +#define FAST_BGR2YV12 // use 7-bit instead of 15-bit coefficients void (*rgb24to32)(const uint8_t *src, uint8_t *dst, long src_size); void (*rgb24to16)(const uint8_t *src, uint8_t *dst, long src_size); @@ -149,8 +149,8 @@ static uint64_t __attribute__((aligned(8))) dither8[2]={ #define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) #define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5)) -//Note: we have C, MMX, MMX2, 3DNOW version therse no 3DNOW+MMX2 one -//Plain C versions +//Note: We have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW + MMX2 one. +//plain C versions #undef HAVE_MMX #undef HAVE_MMX2 #undef HAVE_3DNOW @@ -190,10 +190,10 @@ static uint64_t __attribute__((aligned(8))) dither8[2]={ #endif //ARCH_X86 || ARCH_X86_64 /* - rgb15->rgb16 Original by Strepto/Astral + RGB15->RGB16 original by Strepto/Astral ported to gcc & bugfixed : A'rpi MMX2, 3DNOW optimization by Nick Kurshev - 32bit c version, and and&add trick by Michael Niedermayer + 32-bit C version, and and&add trick by Michael Niedermayer */ void sws_rgb2rgb_init(int flags){ @@ -266,7 +266,7 @@ void palette8torgb24(const uint8_t *src, uint8_t *dst, long num_pixels, const ui { long i; /* - writes 1 byte o much and might cause alignment issues on some architectures? + Writes 1 byte too much and might cause alignment issues on some architectures? for (i=0; i<num_pixels; i++) ((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[src[i]]; */ @@ -284,7 +284,7 @@ void palette8tobgr24(const uint8_t *src, uint8_t *dst, long num_pixels, const ui { long i; /* - writes 1 byte o much and might cause alignment issues on some architectures? + Writes 1 byte too much and might cause alignment issues on some architectures? for (i=0; i<num_pixels; i++) ((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[src[i]]; */ @@ -299,7 +299,7 @@ void palette8tobgr24(const uint8_t *src, uint8_t *dst, long num_pixels, const ui } /** - * Palette is assumed to contain bgr16, see rgb32to16 to convert the palette + * Palette is assumed to contain BGR16, see rgb32to16 to convert the palette. */ void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/rgb2rgb.h b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/rgb2rgb.h @@ -1,8 +1,8 @@ /* - * rgb2rgb.h, Software RGB to RGB convertor - * pluralize by Software PAL8 to RGB convertor - * Software YUV to YUV convertor - * Software YUV to RGB convertor + * software RGB to RGB converter + * pluralize by Software PAL8 to RGB converter + * Software YUV to YUV converter + * Software YUV to RGB converter * Written by Nick Kurshev. * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) * @@ -28,7 +28,7 @@ #include <inttypes.h> -/* A full collection of rgb to rgb(bgr) convertors */ +/* A full collection of RGB to RGB(BGR) converters */ extern void (*rgb24to32) (const uint8_t *src, uint8_t *dst, long src_size); extern void (*rgb24to16) (const uint8_t *src, uint8_t *dst, long src_size); extern void (*rgb24to15) (const uint8_t *src, uint8_t *dst, long src_size); @@ -71,53 +71,49 @@ extern void palette8torgb15(const uint8_t *src, uint8_t *dst, long num_pixels, c extern void palette8tobgr15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); /** - * - * height should be a multiple of 2 and width should be a multiple of 16 (if this is a - * problem for anyone then tell me, and ill fix it) - * chrominance data is only taken from every secound line others are ignored FIXME write HQ version + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) + * Chrominance data is only taken from every second line, others are ignored. + * FIXME: Write HQ version. */ //void uyvytoyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, /** - * - * height should be a multiple of 2 and width should be a multiple of 16 (if this is a - * problem for anyone then tell me, and ill fix it) + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) */ extern void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, long width, long height, long lumStride, long chromStride, long dstStride); /** - * - * width should be a multiple of 16 + * Width should be a multiple of 16. */ extern void (*yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, long width, long height, long lumStride, long chromStride, long dstStride); /** - * - * height should be a multiple of 2 and width should be a multiple of 16 (if this is a - * problem for anyone then tell me, and ill fix it) + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) */ extern void (*yuy2toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, long width, long height, long lumStride, long chromStride, long srcStride); /** - * - * height should be a multiple of 2 and width should be a multiple of 16 (if this is a - * problem for anyone then tell me, and ill fix it) + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) */ extern void (*yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, long width, long height, long lumStride, long chromStride, long dstStride); /** - * - * height should be a multiple of 2 and width should be a multiple of 2 (if this is a - * problem for anyone then tell me, and ill fix it) - * chrominance data is only taken from every secound line others are ignored FIXME write HQ version + * Height should be a multiple of 2 and width should be a multiple of 2. + * (If this is a problem for anyone then tell me, and I will fix it.) + * Chrominance data is only taken from every second line, others are ignored. + * FIXME: Write HQ version. */ extern void (*rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, long width, long height, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/rgb2rgb_template.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/rgb2rgb_template.c @@ -1,11 +1,11 @@ /* - * rgb2rgb.c, Software RGB to RGB convertor - * pluralize by Software PAL8 to RGB convertor - * Software YUV to YUV convertor - * Software YUV to RGB convertor - * Written by Nick Kurshev. - * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) - * lot of big-endian byteorder fixes by Alex Beregszaszi + * software RGB to RGB converter + * pluralize by software PAL8 to RGB converter + * software YUV to YUV converter + * software YUV to RGB converter + * Written by Nick Kurshev. + * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) + * lot of big-endian byte order fixes by Alex Beregszaszi * * This file is part of FFmpeg. * @@ -23,7 +23,7 @@ * along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * The C code (not assembly, mmx, ...) of this file can be used + * The C code (not assembly, MMX, ...) of this file can be used * under the LGPL license. */ @@ -229,10 +229,10 @@ static inline void RENAME(rgb32to24)(const uint8_t *src, uint8_t *dst, long src_ } /* - Original by Strepto/Astral - ported to gcc & bugfixed : A'rpi + original by Strepto/Astral + ported to gcc & bugfixed: A'rpi MMX2, 3DNOW optimization by Nick Kurshev - 32 bit C version, and and&add trick by Michael Niedermayer + 32-bit C version, and and&add trick by Michael Niedermayer */ static inline void RENAME(rgb15to16)(const uint8_t *src, uint8_t *dst, long src_size) { @@ -926,9 +926,9 @@ static inline void RENAME(rgb24tobgr15)(const uint8_t *src, uint8_t *dst, long s ---------------- 1 1 0 1 1 1 1 0 |=======| |===| - | Leftmost Bits Repeated to Fill Open Bits + | leftmost bits repeated to fill open bits | - Original Bits + original bits */ static inline void RENAME(rgb15to24)(const uint8_t *src, uint8_t *dst, long src_size) { @@ -1006,7 +1006,7 @@ static inline void RENAME(rgb15to24)(const uint8_t *src, uint8_t *dst, long src_ :"=m"(*d) :"m"(*s),"m"(mask15b),"m"(mask15g),"m"(mask15r), "m"(mmx_null) :"memory"); - /* Borrowed 32 to 24 */ + /* borrowed 32 to 24 */ asm volatile( "movq %%mm0, %%mm4 \n\t" "movq %%mm3, %%mm5 \n\t" @@ -1147,7 +1147,7 @@ static inline void RENAME(rgb16to24)(const uint8_t *src, uint8_t *dst, long src_ :"=m"(*d) :"m"(*s),"m"(mask16b),"m"(mask16g),"m"(mask16r),"m"(mmx_null) :"memory"); - /* Borrowed 32 to 24 */ + /* borrowed 32 to 24 */ asm volatile( "movq %%mm0, %%mm4 \n\t" "movq %%mm3, %%mm5 \n\t" @@ -1479,7 +1479,7 @@ static inline void RENAME(rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long s asm volatile(SFENCE:::"memory"); asm volatile(EMMS:::"memory"); - if (mmx_size==23) return; //finihsed, was multiple of 8 + if (mmx_size==23) return; //finished, was multiple of 8 src+= src_size; dst+= src_size; @@ -1638,8 +1638,8 @@ asm( EMMS" \n\t" } /** - * Height should be a multiple of 2 and width should be a multiple of 16 (if - * this is a problem for anyone then tell me, and I will fix it). + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) */ static inline void RENAME(yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, long width, long height, @@ -1720,7 +1720,7 @@ static inline void RENAME(yuvPlanartouyvy)(const uint8_t *ysrc, const uint8_t *u (vc[0] << 8) + (yc[1] << 0); #else *idst++ = uc[0] + (yc[0] << 8) + - (vc[0] << 16) + (yc[1] << 24); + (vc[0] << 16) + (yc[1] << 24); #endif yc += 2; uc++; @@ -1744,8 +1744,8 @@ asm( EMMS" \n\t" } /** - * Height should be a multiple of 2 and width should be a multiple of 16 (if - * this is a problem for anyone then tell me, and I will fix it). + * Height should be a multiple of 2 and width should be a multiple of 16 + * (If this is a problem for anyone then tell me, and I will fix it.) */ static inline void RENAME(yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, long width, long height, @@ -1766,8 +1766,8 @@ static inline void RENAME(yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usr } /** - * Height should be a multiple of 2 and width should be a multiple of 16 (if - * this is a problem for anyone then tell me, and I will fix it). + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) */ static inline void RENAME(yuy2toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, long width, long height, @@ -2002,9 +2002,9 @@ asm volatile( EMMS" \n\t" } /** - * Height should be a multiple of 2 and width should be a multiple of 16 (if - * this is a problem for anyone then tell me, and I will fix it). - * Chrominance data is only taken from every secound line, others are ignored. + * Height should be a multiple of 2 and width should be a multiple of 16. + * (If this is a problem for anyone then tell me, and I will fix it.) + * Chrominance data is only taken from every second line, others are ignored. * FIXME: Write HQ version. */ static inline void RENAME(uyvytoyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, @@ -2128,9 +2128,9 @@ asm volatile( EMMS" \n\t" } /** - * Height should be a multiple of 2 and width should be a multiple of 2 (if - * this is a problem for anyone then tell me, and I will fix it). - * Chrominance data is only taken from every secound line, + * Height should be a multiple of 2 and width should be a multiple of 2. + * (If this is a problem for anyone then tell me, and I will fix it.) + * Chrominance data is only taken from every second line, * others are ignored in the C version. * FIXME: Write HQ version. */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale.c @@ -72,7 +72,6 @@ untested special converters #include "rgb2rgb.h" #include "libavutil/x86_cpu.h" #include "libavutil/bswap.h" -#include "libavcodec/opt.h" #undef MOVNTQ #undef PAVGB @@ -88,12 +87,6 @@ untested special converters #define RET 0xC3 //near return opcode for X86 -#ifdef MP_DEBUG -#define ASSERT(x) assert(x); -#else -#define ASSERT(x) ; -#endif - #ifdef M_PI #define PI M_PI #else @@ -238,44 +231,6 @@ extern const uint8_t dither_8x8_32[8][8]; extern const uint8_t dither_8x8_73[8][8]; extern const uint8_t dither_8x8_220[8][8]; -static const char * sws_context_to_name(void * ptr) { - return "swscaler"; -} - -#define OFFSET(x) offsetof(SwsContext, x) -#define DEFAULT 0 -#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM - -static const AVOption options[] = { - { "sws_flags", "scaler/cpu flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, 0, UINT_MAX, VE, "sws_flags" }, - { "fast_bilinear", "fast bilinear", 0, FF_OPT_TYPE_CONST, SWS_FAST_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bilinear", "bilinear", 0, FF_OPT_TYPE_CONST, SWS_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bicubic", "bicubic", 0, FF_OPT_TYPE_CONST, SWS_BICUBIC, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "experimental", "experimental", 0, FF_OPT_TYPE_CONST, SWS_X, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "neighbor", "nearest neighbor", 0, FF_OPT_TYPE_CONST, SWS_POINT, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "area", "averaging area", 0, FF_OPT_TYPE_CONST, SWS_AREA, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bicublin", "luma bicubic, chroma bilinear", 0, FF_OPT_TYPE_CONST, SWS_BICUBLIN, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "gauss", "gaussian", 0, FF_OPT_TYPE_CONST, SWS_GAUSS, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "sinc", "sinc", 0, FF_OPT_TYPE_CONST, SWS_SINC, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "lanczos", "lanczos", 0, FF_OPT_TYPE_CONST, SWS_LANCZOS, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, SWS_SPLINE, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "print_info", "print info", 0, FF_OPT_TYPE_CONST, SWS_PRINT_INFO, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, SWS_ACCURATE_RND, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "mmx", "MMX SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "mmx2", "MMX2 SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX2, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "3dnow", "3DNOW SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_3DNOW, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "altivec", "AltiVec SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_ALTIVEC, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bfin", "Blackfin SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_BFIN, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INT, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INP, INT_MIN, INT_MAX, VE, "sws_flags" }, - { NULL } -}; - -#undef VE -#undef DEFAULT - -static const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options }; - const char *sws_format_name(enum PixelFormat format) { switch (format) { @@ -1060,7 +1015,7 @@ static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outF else if (flags&SWS_BILINEAR) sizeFactor= 2.0; else { sizeFactor= 0.0; //GCC warning killer - ASSERT(0) + assert(0); } if (xInc1 <= 1.0) filterSizeInSrc= sizeFactor; // upscale @@ -1145,7 +1100,7 @@ static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outF } else { coeff= 0.0; //GCC warning killer - ASSERT(0) + assert(0); } filter[i*filterSize + j]= coeff; @@ -1158,11 +1113,11 @@ static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outF /* apply src & dst Filter to filter -> filter2 av_free(filter); */ - ASSERT(filterSize>0) + assert(filterSize>0); filter2Size= filterSize; if (srcFilter) filter2Size+= srcFilter->length - 1; if (dstFilter) filter2Size+= dstFilter->length - 1; - ASSERT(filter2Size>0) + assert(filter2Size>0); filter2= av_malloc(filter2Size*dstW*sizeof(double)); for (i=0; i<dstW; i++) @@ -1177,7 +1132,7 @@ static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outF if (srcFilter) outVec= sws_getConvVec(srcFilter, &scaleFilter); else outVec= &scaleFilter; - ASSERT(outVec->length == filter2Size) + assert(outVec->length == filter2Size); //FIXME dstFilter for (j=0; j<outVec->length; j++) @@ -1252,14 +1207,14 @@ static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outF filterAlign= 1; } - ASSERT(minFilterSize > 0) + assert(minFilterSize > 0); filterSize= (minFilterSize +(filterAlign-1)) & (~(filterAlign-1)); - ASSERT(filterSize > 0) + assert(filterSize > 0); if (filterSize >= MAX_FILTER_SIZE) - { - av_free(filter2); + { + av_free(filter2); return -1; - } + } filter= av_malloc(filterSize*dstW*sizeof(double)); *outFilterSize= filterSize; @@ -1734,62 +1689,62 @@ static int yvu9toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int } /* unscaled copy like stuff (assumes nearly identical formats) */ -static int simpleCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, - int srcSliceH, uint8_t* dst[], int dstStride[]){ - - if (isPacked(c->srcFormat)) +static int packedCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + if (dstStride[0]==srcStride[0] && srcStride[0] > 0) + memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); + else { - if (dstStride[0]==srcStride[0] && srcStride[0] > 0) - memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); - else - { - int i; - uint8_t *srcPtr= src[0]; - uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; - int length=0; + int i; + uint8_t *srcPtr= src[0]; + uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; + int length=0; - /* universal length finder */ - while(length+c->srcW <= FFABS(dstStride[0]) - && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW; - ASSERT(length!=0); + /* universal length finder */ + while(length+c->srcW <= FFABS(dstStride[0]) + && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW; + assert(length!=0); - for (i=0; i<srcSliceH; i++) - { - memcpy(dstPtr, srcPtr, length); - srcPtr+= srcStride[0]; - dstPtr+= dstStride[0]; - } + for (i=0; i<srcSliceH; i++) + { + memcpy(dstPtr, srcPtr, length); + srcPtr+= srcStride[0]; + dstPtr+= dstStride[0]; } } - else - { /* Planar YUV or gray */ - int plane; - for (plane=0; plane<3; plane++) - { - int length= plane==0 ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); - int y= plane==0 ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); - int height= plane==0 ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); + return srcSliceH; +} - if ((isGray(c->srcFormat) || isGray(c->dstFormat)) && plane>0) - { - if (!isGray(c->dstFormat)) - memset(dst[plane], 128, dstStride[plane]*height); - } +static int planarCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + int plane; + for (plane=0; plane<3; plane++) + { + int length= plane==0 ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); + int y= plane==0 ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); + int height= plane==0 ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); + + if ((isGray(c->srcFormat) || isGray(c->dstFormat)) && plane>0) + { + if (!isGray(c->dstFormat)) + memset(dst[plane], 128, dstStride[plane]*height); + } + else + { + if (dstStride[plane]==srcStride[plane] && srcStride[plane] > 0) + memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]); else { - if (dstStride[plane]==srcStride[plane] && srcStride[plane] > 0) - memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]); - else + int i; + uint8_t *srcPtr= src[plane]; + uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; + for (i=0; i<height; i++) { - int i; - uint8_t *srcPtr= src[plane]; - uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; - for (i=0; i<height; i++) - { - memcpy(dstPtr, srcPtr, length); - srcPtr+= srcStride[plane]; - dstPtr+= dstStride[plane]; - } + memcpy(dstPtr, srcPtr, length); + srcPtr+= srcStride[plane]; + dstPtr+= dstStride[plane]; } } } @@ -2062,6 +2017,24 @@ SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH return NULL; } + i= flags & ( SWS_POINT + |SWS_AREA + |SWS_BILINEAR + |SWS_FAST_BILINEAR + |SWS_BICUBIC + |SWS_X + |SWS_GAUSS + |SWS_LANCZOS + |SWS_SINC + |SWS_SPLINE + |SWS_BICUBLIN); + if(!i || (i & (i-1))) + { + av_log(NULL, AV_LOG_ERROR, "swScaler: Exactly one scaler algorithm must be choosen\n"); + return NULL; + } + + /* sanity check */ if (srcW<4 || srcH<1 || dstW<8 || dstH<1) //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code { @@ -2211,7 +2184,10 @@ SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH || (isPlanarYUV(srcFormat) && isGray(dstFormat)) || (isPlanarYUV(dstFormat) && isGray(srcFormat))) { - c->swScale= simpleCopy; + if (isPacked(c->srcFormat)) + c->swScale= packedCopy; + else /* Planar YUV or gray */ + c->swScale= planarCopy; } /* gray16{le,be} conversions */ @@ -2388,7 +2364,7 @@ SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH assert(2*VOFW == VOF); - ASSERT(c->chrDstH <= dstH) + assert(c->chrDstH <= dstH); if (flags&SWS_PRINT_INFO) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_altivec_template.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_altivec_template.c @@ -245,12 +245,12 @@ static inline void hScale_altivec_real(int16_t *dst, int dstW, uint8_t *src, int src_v = vec_mergeh(src_v, (vector signed short)vzero); filter_v = vec_ld(i << 3, filter); - // the 3 above is 2 (filterSize == 4) + 1 (sizeof(short) == 2) + // The 3 above is 2 (filterSize == 4) + 1 (sizeof(short) == 2). - // the neat trick : we only care for half the elements, + // The neat trick: We only care for half the elements, // high or low depending on (i<<3)%16 (it's 0 or 8 here), - // and we're going to use vec_mule, so we chose - // carefully how to "unpack" the elements into the even slots + // and we're going to use vec_mule, so we choose + // carefully how to "unpack" the elements into the even slots. if ((i << 3) % 16) filter_v = vec_mergel(filter_v, (vector signed short)vzero); else @@ -405,12 +405,12 @@ static inline int yv12toyuy2_unscaled_altivec(SwsContext *c, uint8_t* src[], int return srcSliceH; } - /* this code assume: + /* This code assumes: 1) dst is 16 bytes-aligned 2) dstStride is a multiple of 16 3) width is a multiple of 16 - 4) lum&chrom stride are multiple of 8 + 4) lum & chrom stride are multiples of 8 */ for (y=0; y<height; y++) { @@ -482,12 +482,12 @@ static inline int yv12touyvy_unscaled_altivec(SwsContext *c, uint8_t* src[], int return srcSliceH; } - /* this code assume: + /* This code assumes: 1) dst is 16 bytes-aligned 2) dstStride is a multiple of 16 3) width is a multiple of 16 - 4) lum&chrom stride are multiple of 8 + 4) lum & chrom stride are multiples of 8 */ for (y=0; y<height; y++) { diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_avoption.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_avoption.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avutil.h" +#include "libavcodec/opt.h" +#include "swscale.h" +#include "swscale_internal.h" + +static const char * sws_context_to_name(void * ptr) { + return "swscaler"; +} + +#define OFFSET(x) offsetof(SwsContext, x) +#define DEFAULT 0 +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM + +static const AVOption options[] = { + { "sws_flags", "scaler/cpu flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, 0, UINT_MAX, VE, "sws_flags" }, + { "fast_bilinear", "fast bilinear", 0, FF_OPT_TYPE_CONST, SWS_FAST_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bilinear", "bilinear", 0, FF_OPT_TYPE_CONST, SWS_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bicubic", "bicubic", 0, FF_OPT_TYPE_CONST, SWS_BICUBIC, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "experimental", "experimental", 0, FF_OPT_TYPE_CONST, SWS_X, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "neighbor", "nearest neighbor", 0, FF_OPT_TYPE_CONST, SWS_POINT, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "area", "averaging area", 0, FF_OPT_TYPE_CONST, SWS_AREA, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bicublin", "luma bicubic, chroma bilinear", 0, FF_OPT_TYPE_CONST, SWS_BICUBLIN, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "gauss", "gaussian", 0, FF_OPT_TYPE_CONST, SWS_GAUSS, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "sinc", "sinc", 0, FF_OPT_TYPE_CONST, SWS_SINC, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "lanczos", "lanczos", 0, FF_OPT_TYPE_CONST, SWS_LANCZOS, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, SWS_SPLINE, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "print_info", "print info", 0, FF_OPT_TYPE_CONST, SWS_PRINT_INFO, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, SWS_ACCURATE_RND, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "mmx", "MMX SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "mmx2", "MMX2 SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX2, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "3dnow", "3DNOW SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_3DNOW, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "altivec", "AltiVec SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_ALTIVEC, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bfin", "Blackfin SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_BFIN, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INT, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INP, INT_MIN, INT_MAX, VE, "sws_flags" }, + { NULL } +}; + +const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options }; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_bfin.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_bfin.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * Blackfin Software Video SCALER Operations + * Blackfin software video scaler operations * * This file is part of FFmpeg. * diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_internal.h b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_internal.h @@ -37,7 +37,7 @@ typedef int (*SwsFunc)(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]); -/* this struct should be aligned on at least 32-byte boundary */ +/* This struct should be aligned on at least a 32-byte boundary. */ typedef struct SwsContext{ /** * info on struct for av_log @@ -73,7 +73,7 @@ typedef struct SwsContext{ int16_t *vChrFilter; int16_t *vChrFilterPos; - uint8_t formatConvBuffer[VOF]; //FIXME dynamic alloc, but we have to change a lot of code for this to be useful + uint8_t formatConvBuffer[VOF]; //FIXME dynamic allocation, but we have to change a lot of code for this to be useful int hLumFilterSize; int hChrFilterSize; @@ -122,7 +122,7 @@ typedef struct SwsContext{ #define V_OFFSET "10*8" #define LUM_MMX_FILTER_OFFSET "11*8" #define CHR_MMX_FILTER_OFFSET "11*8+4*4*256" -#define DSTW_OFFSET "11*8+4*4*256*2" //do not change, it is hardcoded in the asm +#define DSTW_OFFSET "11*8+4*4*256*2" //do not change, it is hardcoded in the ASM #define ESP_OFFSET "11*8+4*4*256*2+8" #define VROUNDER_OFFSET "11*8+4*4*256*2+16" #define U_TEMP "11*8+4*4*256*2+24" @@ -278,4 +278,6 @@ static inline int fmt_depth(int fmt) extern const DECLARE_ALIGNED(8, uint64_t, ff_dither4[2]); extern const DECLARE_ALIGNED(8, uint64_t, ff_dither8[2]); +extern const AVClass sws_context_class; + #endif /* FFMPEG_SWSCALE_INTERNAL_H */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_template.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/swscale_template.c @@ -17,8 +17,8 @@ * along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * the C code (not assembly, mmx, ...) of this file can be used - * under the LGPL license too + * The C code (not assembly, MMX, ...) of this file can be used + * under the LGPL license. */ #undef REAL_MOVNTQ @@ -30,7 +30,7 @@ #undef SFENCE #ifdef HAVE_3DNOW -/* On K6 femms is faster of emms. On K7 femms is directly mapped on emms. */ +/* On K6 femms is faster than emms. On K7 femms is directly mapped on emms. */ #define EMMS "femms" #else #define EMMS "emms" @@ -181,6 +181,24 @@ "add $8, %%"REG_a" \n\t"\ "jnc 1b \n\t" +#define YSCALEYUV2YV121_ACCURATE \ + "mov %2, %%"REG_a" \n\t"\ + "pcmpeqw %%mm7, %%mm7 \n\t"\ + "psrlw $15, %%mm7 \n\t"\ + "psllw $6, %%mm7 \n\t"\ + ASMALIGN(4) /* FIXME Unroll? */\ + "1: \n\t"\ + "movq (%0, %%"REG_a", 2), %%mm0 \n\t"\ + "movq 8(%0, %%"REG_a", 2), %%mm1 \n\t"\ + "paddw %%mm7, %%mm0 \n\t"\ + "paddw %%mm7, %%mm1 \n\t"\ + "psraw $7, %%mm0 \n\t"\ + "psraw $7, %%mm1 \n\t"\ + "packuswb %%mm1, %%mm0 \n\t"\ + MOVNTQ(%%mm0, (%1, %%REGa))\ + "add $8, %%"REG_a" \n\t"\ + "jnc 1b \n\t" + /* :: "m" (-lumFilterSize), "m" (-chrFilterSize), "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4), @@ -969,38 +987,40 @@ yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize, dest, uDest, dstW, chrDstW, dstFormat); } -static inline void RENAME(yuv2yuv1)(int16_t *lumSrc, int16_t *chrSrc, +static inline void RENAME(yuv2yuv1)(SwsContext *c, int16_t *lumSrc, int16_t *chrSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, long dstW, long chrDstW) { #ifdef HAVE_MMX - if (uDest) - { - asm volatile( - YSCALEYUV2YV121 - :: "r" (chrSrc + chrDstW), "r" (uDest + chrDstW), - "g" (-chrDstW) - : "%"REG_a - ); + long p= uDest ? 3 : 1; + uint8_t *src[3]= {lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW}; + uint8_t *dst[3]= {dest, uDest, vDest}; + long counter[3] = {dstW, chrDstW, chrDstW}; - asm volatile( - YSCALEYUV2YV121 - :: "r" (chrSrc + VOFW + chrDstW), "r" (vDest + chrDstW), - "g" (-chrDstW) - : "%"REG_a - ); + if (c->flags & SWS_ACCURATE_RND){ + while(p--){ + asm volatile( + YSCALEYUV2YV121_ACCURATE + :: "r" (src[p]), "r" (dst[p] + counter[p]), + "g" (-counter[p]) + : "%"REG_a + ); + } + }else{ + while(p--){ + asm volatile( + YSCALEYUV2YV121 + :: "r" (src[p]), "r" (dst[p] + counter[p]), + "g" (-counter[p]) + : "%"REG_a + ); + } } - asm volatile( - YSCALEYUV2YV121 - :: "r" (lumSrc + dstW), "r" (dest + dstW), - "g" (-dstW) - : "%"REG_a - ); #else int i; for (i=0; i<dstW; i++) { - int val= lumSrc[i]>>7; + int val= (lumSrc[i]+64)>>7; if (val&256){ if (val<0) val=0; @@ -1013,8 +1033,8 @@ static inline void RENAME(yuv2yuv1)(int16_t *lumSrc, int16_t *chrSrc, if (uDest) for (i=0; i<chrDstW; i++) { - int u=chrSrc[i]>>7; - int v=chrSrc[i + VOFW]>>7; + int u=(chrSrc[i ]+64)>>7; + int v=(chrSrc[i + VOFW]+64)>>7; if ((u|v)&256){ if (u<0) u=0; @@ -1503,7 +1523,7 @@ static inline void RENAME(yuv2packed1)(SwsContext *c, uint16_t *buf0, uint16_t * const int yalpha1=0; int i; - uint16_t *buf1= buf0; //FIXME needed for the rgb1/bgr1 + uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 const int yalpha= 4096; //FIXME ... if (flags&SWS_FULL_CHR_H_INT) @@ -1700,7 +1720,7 @@ static inline void RENAME(yuv2packed1)(SwsContext *c, uint16_t *buf0, uint16_t * } } -//FIXME yuy2* can read upto 7 samples to much +//FIXME yuy2* can read up to 7 samples too much static inline void RENAME(yuy2ToY)(uint8_t *dst, uint8_t *src, long width) { @@ -2297,7 +2317,7 @@ static inline void RENAME(palToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, } } -// Bilinear / Bicubic scaling +// bilinear / bicubic scaling static inline void RENAME(hScale)(int16_t *dst, int dstW, uint8_t *src, int srcW, int xInc, int16_t *filter, int16_t *filterPos, long filterSize) { @@ -2544,7 +2564,7 @@ static inline void RENAME(hyscale)(uint16_t *dst, long dstWidth, uint8_t *src, i } #ifdef HAVE_MMX - // use the new MMX scaler if the mmx2 can't be used (it is faster than the x86 ASM one) + // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one). if (!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed)) #else if (!(flags&SWS_FAST_BILINEAR)) @@ -2552,7 +2572,7 @@ static inline void RENAME(hyscale)(uint16_t *dst, long dstWidth, uint8_t *src, i { RENAME(hScale)(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize); } - else // Fast Bilinear upscale / crap downscale + else // fast bilinear upscale / crap downscale { #if defined(ARCH_X86) #ifdef HAVE_MMX2 @@ -2761,7 +2781,7 @@ inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, } #ifdef HAVE_MMX - // use the new MMX scaler if the mmx2 can't be used (it is faster than the x86 ASM one) + // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one). if (!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed)) #else if (!(flags&SWS_FAST_BILINEAR)) @@ -2770,7 +2790,7 @@ inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, RENAME(hScale)(dst , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); RENAME(hScale)(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); } - else // Fast Bilinear upscale / crap downscale + else // fast bilinear upscale / crap downscale { #if defined(ARCH_X86) #ifdef HAVE_MMX2 @@ -2890,8 +2910,8 @@ FUNNY_UV_CODE "cmp %2, %%"REG_a" \n\t" " jb 1b \n\t" -/* GCC-3.3 makes MPlayer crash on IA-32 machines when using "g" operand here, - which is needed to support GCC-4.0 */ +/* GCC 3.3 makes MPlayer crash on IA-32 machines when using "g" operand here, + which is needed to support GCC 4.0. */ #if defined(ARCH_X86_64) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) :: "m" (src1), "m" (dst), "g" ((long)dstWidth), "m" (xInc_shr16), "m" (xInc_mask), #else @@ -2963,7 +2983,7 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s int lastDstY; uint8_t *pal=NULL; - /* vars whch will change and which we need to storw back in the context */ + /* vars which will change and which we need to store back in the context */ int dstY= c->dstY; int lumBufIndex= c->lumBufIndex; int chrBufIndex= c->chrBufIndex; @@ -3004,13 +3024,14 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s if (flags & SWS_PRINT_INFO && firstTime) { av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n" - " ->cannot do aligned memory acesses anymore\n"); + " ->cannot do aligned memory accesses anymore\n"); firstTime=0; } } - /* Note the user might start scaling the picture in the middle so this will not get executed - this is not really intended but works currently, so ppl might do it */ + /* Note the user might start scaling the picture in the middle so this + will not get executed. This is not really intended but works + currently, so people might do it. */ if (srcSliceY ==0){ lumBufIndex=0; chrBufIndex=0; @@ -3038,8 +3059,8 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1; if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1; //printf("%d %d %d\n", firstChrSrcY, lastInChrBuf, vChrBufSize); - ASSERT(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1) - ASSERT(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1) + assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1); + assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1); // Do we have enough lines in this slice to output the dstY line if (lastLumSrcY < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample)) @@ -3050,9 +3071,9 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; lumBufIndex++; //printf("%d %d %d %d\n", lumBufIndex, vLumBufSize, lastInLumBuf, lastLumSrcY); - ASSERT(lumBufIndex < 2*vLumBufSize) - ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH) - ASSERT(lastInLumBuf + 1 - srcSliceY >= 0) + assert(lumBufIndex < 2*vLumBufSize); + assert(lastInLumBuf + 1 - srcSliceY < srcSliceH); + assert(lastInLumBuf + 1 - srcSliceY >= 0); //printf("%d %d\n", lumBufIndex, vLumBufSize); RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc, flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize, @@ -3065,9 +3086,9 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1]; uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2]; chrBufIndex++; - ASSERT(chrBufIndex < 2*vChrBufSize) - ASSERT(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH)) - ASSERT(lastInChrBuf + 1 - chrSrcSliceY >= 0) + assert(chrBufIndex < 2*vChrBufSize); + assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH)); + assert(lastInChrBuf + 1 - chrSrcSliceY >= 0); //FIXME replace parameters through context struct (some at least) if (!(isGray(srcFormat) || isGray(dstFormat))) @@ -3093,9 +3114,9 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s { uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; lumBufIndex++; - ASSERT(lumBufIndex < 2*vLumBufSize) - ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH) - ASSERT(lastInLumBuf + 1 - srcSliceY >= 0) + assert(lumBufIndex < 2*vLumBufSize); + assert(lastInLumBuf + 1 - srcSliceY < srcSliceH); + assert(lastInLumBuf + 1 - srcSliceY >= 0); RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc, flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize, funnyYCode, c->srcFormat, formatConvBuffer, @@ -3107,9 +3128,9 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1]; uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2]; chrBufIndex++; - ASSERT(chrBufIndex < 2*vChrBufSize) - ASSERT(lastInChrBuf + 1 - chrSrcSliceY < chrSrcSliceH) - ASSERT(lastInChrBuf + 1 - chrSrcSliceY >= 0) + assert(chrBufIndex < 2*vChrBufSize); + assert(lastInChrBuf + 1 - chrSrcSliceY < chrSrcSliceH); + assert(lastInChrBuf + 1 - chrSrcSliceY >= 0); if (!(isGray(srcFormat) || isGray(dstFormat))) RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc, @@ -3182,11 +3203,11 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s { const int chrSkipMask= (1<<c->chrDstVSubSample)-1; if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi - if (vLumFilterSize == 1 && vChrFilterSize == 1) // Unscaled YV12 + if (vLumFilterSize == 1 && vChrFilterSize == 1) // unscaled YV12 { int16_t *lumBuf = lumPixBuf[0]; int16_t *chrBuf= chrPixBuf[0]; - RENAME(yuv2yuv1)(lumBuf, chrBuf, dest, uDest, vDest, dstW, chrDstW); + RENAME(yuv2yuv1)(c, lumBuf, chrBuf, dest, uDest, vDest, dstW, chrDstW); } else //General YV12 { @@ -3198,15 +3219,15 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s } else { - ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); - ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); - if (vLumFilterSize == 1 && vChrFilterSize == 2) //Unscaled RGB + assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); + assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); + if (vLumFilterSize == 1 && vChrFilterSize == 2) //unscaled RGB { int chrAlpha= vChrFilter[2*dstY+1]; RENAME(yuv2packed1)(c, *lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1), dest, dstW, chrAlpha, dstFormat, flags, dstY); } - else if (vLumFilterSize == 2 && vChrFilterSize == 2) //BiLinear Upscale RGB + else if (vLumFilterSize == 2 && vChrFilterSize == 2) //bilinear upscale RGB { int lumAlpha= vLumFilter[2*dstY+1]; int chrAlpha= vChrFilter[2*dstY+1]; @@ -3217,7 +3238,7 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s RENAME(yuv2packed2)(c, *lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1), dest, dstW, lumAlpha, chrAlpha, dstY); } - else //General RGB + else //general RGB { RENAME(yuv2packedX)(c, vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, @@ -3249,8 +3270,8 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s } else { - ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); - ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); + assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); + assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); yuv2packedXinC(c, vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb.c @@ -39,7 +39,7 @@ #include "swscale.h" #include "swscale_internal.h" -#define DITHER1XBPP // only for mmx +#define DITHER1XBPP // only for MMX const uint8_t __attribute__((aligned(8))) dither_2x2_4[2][8]={ { 1, 3, 1, 3, 1, 3, 1, 3, }, @@ -155,8 +155,8 @@ DECLARE_ASM_CONST(8, uint64_t, mmx_00ffw) = 0x00ff00ff00ff00ffULL; DECLARE_ASM_CONST(8, uint64_t, mmx_redmask) = 0xf8f8f8f8f8f8f8f8ULL; DECLARE_ASM_CONST(8, uint64_t, mmx_grnmask) = 0xfcfcfcfcfcfcfcfcULL; -// the volatile is required because gcc otherwise optimizes some writes away not knowing that these -// are read in the asm block +// The volatile is required because gcc otherwise optimizes some writes away +// not knowing that these are read in the ASM block. static volatile uint64_t attribute_used __attribute__((aligned(8))) b5Dither; static volatile uint64_t attribute_used __attribute__((aligned(8))) g5Dither; static volatile uint64_t attribute_used __attribute__((aligned(8))) g6Dither; @@ -641,7 +641,7 @@ SwsFunc yuv2rgb_get_func_ptr (SwsContext *c) } #endif - av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found\n"); + av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found.\n"); switch(c->dstFormat){ case PIX_FMT_BGR32: diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_altivec.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_altivec.c @@ -1,85 +1,90 @@ /* - marc.hoffman@analog.com March 8, 2004 - - AltiVec acceleration for colorspace conversion revision 0.2 + * AltiVec acceleration for colorspace conversion + * + * copyright (C) 2004 Marc Hoffman <marc.hoffman@analog.com> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * FFmpeg is 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ - convert I420 YV12 to RGB in various formats, - it rejects images that are not in 420 formats - it rejects images that don't have widths of multiples of 16 - it rejects images that don't have heights of multiples of 2 - reject defers to C simulation codes. +/* +Convert I420 YV12 to RGB in various formats, + it rejects images that are not in 420 formats, + it rejects images that don't have widths of multiples of 16, + it rejects images that don't have heights of multiples of 2. +Reject defers to C simulation code. - lots of optimizations to be done here +Lots of optimizations to be done here. - 1. need to fix saturation code, I just couldn't get it to fly with packs and adds. - so we currently use max min to clip +1. Need to fix saturation code. I just couldn't get it to fly with packs + and adds, so we currently use max/min to clip. - 2. the inefficient use of chroma loading needs a bit of brushing up +2. The inefficient use of chroma loading needs a bit of brushing up. - 3. analysis of pipeline stalls needs to be done, use shark to identify pipeline stalls +3. Analysis of pipeline stalls needs to be done. Use shark to identify + pipeline stalls. - MODIFIED to calculate coeffs from currently selected color space. - MODIFIED core to be a macro which you spec the output format. - ADDED UYVY conversion which is never called due to some thing in SWSCALE. - CORRECTED algorithim selection to be strict on input formats. - ADDED runtime detection of altivec. +MODIFIED to calculate coeffs from currently selected color space. +MODIFIED core to be a macro where you specify the output format. +ADDED UYVY conversion which is never called due to some thing in swscale. +CORRECTED algorithim selection to be strict on input formats. +ADDED runtime detection of AltiVec. - ADDED altivec_yuv2packedX vertical scl + RGB converter +ADDED altivec_yuv2packedX vertical scl + RGB converter - March 27,2004 - PERFORMANCE ANALYSIS +March 27,2004 +PERFORMANCE ANALYSIS - The C version use 25% of the processor or ~250Mips for D1 video rawvideo used as test - The ALTIVEC version uses 10% of the processor or ~100Mips for D1 video same sequence +The C version uses 25% of the processor or ~250Mips for D1 video rawvideo +used as test. +The AltiVec version uses 10% of the processor or ~100Mips for D1 video +same sequence. - 720*480*30 ~10MPS +720 * 480 * 30 ~10MPS - so we have roughly 10clocks per pixel this is too high something has to be wrong. +so we have roughly 10 clocks per pixel. This is too high, something has +to be wrong. - OPTIMIZED clip codes to utilize vec_max and vec_packs removing the need for vec_min. +OPTIMIZED clip codes to utilize vec_max and vec_packs removing the +need for vec_min. - OPTIMIZED DST OUTPUT cache/dma controls. we are pretty much - guaranteed to have the input video frame it was just decompressed so - it probably resides in L1 caches. However we are creating the - output video stream this needs to use the DSTST instruction to - optimize for the cache. We couple this with the fact that we are - not going to be visiting the input buffer again so we mark it Least - Recently Used. This shaves 25% of the processor cycles off. +OPTIMIZED DST OUTPUT cache/DMA controls. We are pretty much guaranteed to have +the input video frame, it was just decompressed so it probably resides in L1 +caches. However, we are creating the output video stream. This needs to use the +DSTST instruction to optimize for the cache. We couple this with the fact that +we are not going to be visiting the input buffer again so we mark it Least +Recently Used. This shaves 25% of the processor cycles off. - Now MEMCPY is the largest mips consumer in the system, probably due - to the inefficient X11 stuff. +Now memcpy is the largest mips consumer in the system, probably due +to the inefficient X11 stuff. - GL libraries seem to be very slow on this machine 1.33Ghz PB running - Jaguar, this is not the case for my 1Ghz PB. I thought it might be - a versioning issues, however I have libGL.1.2.dylib for both - machines. ((We need to figure this out now)) +GL libraries seem to be very slow on this machine 1.33Ghz PB running +Jaguar, this is not the case for my 1Ghz PB. I thought it might be +a versioning issue, however I have libGL.1.2.dylib for both +machines. (We need to figure this out now.) - GL2 libraries work now with patch for RGB32 +GL2 libraries work now with patch for RGB32. - NOTE quartz vo driver ARGB32_to_RGB24 consumes 30% of the processor +NOTE: quartz vo driver ARGB32_to_RGB24 consumes 30% of the processor. - Integrated luma prescaling adjustment for saturation/contrast/brightness adjustment. +Integrated luma prescaling adjustment for saturation/contrast/brightness +adjustment. */ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * FFmpeg is 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -138,14 +143,14 @@ typedef signed char sbyte; */ static const vector unsigned char - perm_rgb_0 = (const vector unsigned char)AVV(0x00,0x01,0x10,0x02,0x03,0x11,0x04,0x05, - 0x12,0x06,0x07,0x13,0x08,0x09,0x14,0x0a), - perm_rgb_1 = (const vector unsigned char)AVV(0x0b,0x15,0x0c,0x0d,0x16,0x0e,0x0f,0x17, - 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f), - perm_rgb_2 = (const vector unsigned char)AVV(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x00,0x01,0x18,0x02,0x03,0x19,0x04,0x05), - perm_rgb_3 = (const vector unsigned char)AVV(0x1a,0x06,0x07,0x1b,0x08,0x09,0x1c,0x0a, - 0x0b,0x1d,0x0c,0x0d,0x1e,0x0e,0x0f,0x1f); + perm_rgb_0 = AVV(0x00,0x01,0x10,0x02,0x03,0x11,0x04,0x05, + 0x12,0x06,0x07,0x13,0x08,0x09,0x14,0x0a), + perm_rgb_1 = AVV(0x0b,0x15,0x0c,0x0d,0x16,0x0e,0x0f,0x17, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f), + perm_rgb_2 = AVV(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x00,0x01,0x18,0x02,0x03,0x19,0x04,0x05), + perm_rgb_3 = AVV(0x1a,0x06,0x07,0x1b,0x08,0x09,0x1c,0x0a, + 0x0b,0x1d,0x0c,0x0d,0x1e,0x0e,0x0f,0x1f); #define vec_merge3(x2,x1,x0,y0,y1,y2) \ do { \ @@ -607,18 +612,18 @@ DEFCSP420_CVT (yuv2_bgr24, out_bgr24) // 0123 4567 89ab cdef static const vector unsigned char - demux_u = (const vector unsigned char)AVV(0x10,0x00,0x10,0x00, - 0x10,0x04,0x10,0x04, - 0x10,0x08,0x10,0x08, - 0x10,0x0c,0x10,0x0c), - demux_v = (const vector unsigned char)AVV(0x10,0x02,0x10,0x02, - 0x10,0x06,0x10,0x06, - 0x10,0x0A,0x10,0x0A, - 0x10,0x0E,0x10,0x0E), - demux_y = (const vector unsigned char)AVV(0x10,0x01,0x10,0x03, - 0x10,0x05,0x10,0x07, - 0x10,0x09,0x10,0x0B, - 0x10,0x0D,0x10,0x0F); + demux_u = AVV(0x10,0x00,0x10,0x00, + 0x10,0x04,0x10,0x04, + 0x10,0x08,0x10,0x08, + 0x10,0x0c,0x10,0x0c), + demux_v = AVV(0x10,0x02,0x10,0x02, + 0x10,0x06,0x10,0x06, + 0x10,0x0A,0x10,0x0A, + 0x10,0x0E,0x10,0x0E), + demux_y = AVV(0x10,0x01,0x10,0x03, + 0x10,0x05,0x10,0x07, + 0x10,0x09,0x10,0x0B, + 0x10,0x0D,0x10,0x0F); /* this is so I can play live CCIR raw video diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_bfin.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_bfin.c @@ -1,9 +1,8 @@ /* * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> - * April 20, 2007 * - * Blackfin Video Color Space Converters Operations - * convert I420 YV12 to RGB in various formats, + * Blackfin video color space converter operations + * convert I420 YV12 to RGB in various formats * * This file is part of FFmpeg. * @@ -200,7 +199,7 @@ SwsFunc ff_bfin_yuv2rgb_get_func_ptr (SwsContext *c) return 0; } - av_log(c, AV_LOG_INFO, "BlackFin Accelerated Color Space Converter %s\n", + av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n", sws_format_name (c->dstFormat)); return f; diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_mlib.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_mlib.c @@ -1,5 +1,6 @@ /* - * yuv2rgb_mlib.c, Software YUV to RGB converter using mediaLib + * software YUV to RGB converter using mediaLib + * * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_template.c b/src/plugins/thumbnailffmpeg/ffmpeg/libswscale/yuv2rgb_template.c @@ -1,5 +1,5 @@ /* - * yuv2rgb_mmx.c, Software YUV to RGB converter with Intel MMX "technology" + * yuv2rgb_mmx.c, software YUV to RGB converter with Intel MMX "technology" * * Copyright (C) 2000, Silicon Integrated System Corp. * @@ -31,7 +31,7 @@ #undef SFENCE #ifdef HAVE_3DNOW -/* On K6 femms is faster of emms. On K7 femms is directly mapped on emms. */ +/* On K6 femms is faster than emms. On K7 femms is directly mapped on emms. */ #define EMMS "femms" #else #define EMMS "emms" @@ -147,8 +147,8 @@ static inline int RENAME(yuv420_rgb16)(SwsContext *c, uint8_t* src[], int srcStr g6Dither= ff_dither4[y&1]; g5Dither= ff_dither8[y&1]; r5Dither= ff_dither8[(y+1)&1]; - /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8 - pixels in each iteration */ + /* This MMX assembly code deals with a SINGLE scan line at a time, + * it converts 8 pixels in each iteration. */ asm volatile ( /* load data for start of next scan line */ "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ @@ -156,8 +156,8 @@ static inline int RENAME(yuv420_rgb16)(SwsContext *c, uint8_t* src[], int srcStr "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ //".balign 16 \n\t" "1: \n\t" - /* no speed diference on my p3@500 with prefetch, - * if it is faster for anyone with -benchmark then tell me + /* No speed difference on my p3@500 with prefetch, + * if it is faster for anyone with -benchmark then tell me. PREFETCH" 64(%0) \n\t" PREFETCH" 64(%1) \n\t" PREFETCH" 64(%2) \n\t" @@ -180,7 +180,7 @@ YUV2RGB "movq %%mm0, %%mm5;" /* Copy B7-B0 */ "movq %%mm2, %%mm7;" /* Copy G7-G0 */ - /* convert rgb24 plane to rgb16 pack for pixel 0-3 */ + /* convert RGB24 plane to RGB16 pack for pixel 0-3 */ "punpcklbw %%mm4, %%mm2;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0 */ "punpcklbw %%mm1, %%mm0;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */ @@ -190,7 +190,7 @@ YUV2RGB "movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ MOVNTQ " %%mm0, (%1);" /* store pixel 0-3 */ - /* convert rgb24 plane to rgb16 pack for pixel 0-3 */ + /* convert RGB24 plane to RGB16 pack for pixel 0-3 */ "punpckhbw %%mm4, %%mm7;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0 */ "punpckhbw %%mm1, %%mm5;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */ @@ -242,8 +242,8 @@ static inline int RENAME(yuv420_rgb15)(SwsContext *c, uint8_t* src[], int srcStr g6Dither= ff_dither4[y&1]; g5Dither= ff_dither8[y&1]; r5Dither= ff_dither8[(y+1)&1]; - /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8 - pixels in each iteration */ + /* This MMX assembly code deals with a SINGLE scan line at a time, + * it converts 8 pixels in each iteration. */ asm volatile ( /* load data for start of next scan line */ "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ @@ -271,7 +271,7 @@ YUV2RGB "movq %%mm0, %%mm5;" /* Copy B7-B0 */ "movq %%mm2, %%mm7;" /* Copy G7-G0 */ - /* convert rgb24 plane to rgb16 pack for pixel 0-3 */ + /* convert RGB24 plane to RGB16 pack for pixel 0-3 */ "punpcklbw %%mm4, %%mm2;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 g3_0_0_0 */ "punpcklbw %%mm1, %%mm0;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */ @@ -281,7 +281,7 @@ YUV2RGB "movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ MOVNTQ " %%mm0, (%1);" /* store pixel 0-3 */ - /* convert rgb24 plane to rgb16 pack for pixel 0-3 */ + /* convert RGB24 plane to RGB16 pack for pixel 0-3 */ "punpckhbw %%mm4, %%mm7;" /* 0_0_0_0 0_0_0_0 0_g7g6g5 g4g3_0_0 */ "punpckhbw %%mm1, %%mm5;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */ @@ -326,8 +326,8 @@ static inline int RENAME(yuv420_rgb24)(SwsContext *c, uint8_t* src[], int srcStr uint8_t *pv = src[2] + (y>>1)*srcStride[2]; long index= -h_size/2; - /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8 - pixels in each iteration */ + /* This MMX assembly code deals with a SINGLE scan line at a time, + * it converts 8 pixels in each iteration. */ asm volatile ( /* load data for start of next scan line */ "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ @@ -472,8 +472,8 @@ static inline int RENAME(yuv420_rgb32)(SwsContext *c, uint8_t* src[], int srcStr uint8_t *pv = src[2] + (y>>1)*srcStride[2]; long index= -h_size/2; - /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8 - pixels in each iteration */ + /* This MMX assembly code deals with a SINGLE scan line at a time, + * it converts 8 pixels in each iteration. */ asm volatile ( /* load data for start of next scan line */ "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/tests/ffmpeg.regression.ref b/src/plugins/thumbnailffmpeg/ffmpeg/tests/ffmpeg.regression.ref @@ -181,10 +181,10 @@ efdae2746040dbc27be402b149556f1e *./tests/data/a-adpcm_qt.aiff 281184 ./tests/data/a-adpcm_qt.aiff 5a2084ad27674d5cf3bc2945061e7910 *./tests/data/adpcm_ima_qt.vsynth.out.wav stddev:915.35 PSNR:37.09 bytes:1056768 -628d4789cf9ee16a756ac54b7fd8650d *./tests/data/a-adpcm_ms.wav +88a0c48c9bc6d50a84c408151c6a3d64 *./tests/data/a-adpcm_ms.wav 267320 ./tests/data/a-adpcm_ms.wav -91a84bb4f319a3a0bf0c0441b3d3a529 *./tests/data/adpcm_ms.vsynth.out.wav -stddev:1050.18 PSNR:35.89 bytes:1054720 +d5f98f5136040be42232a34df92d61f2 *./tests/data/adpcm_ms.vsynth.out.wav +stddev:1051.84 PSNR:35.88 bytes:1054720 ab11d9151644cbff27827b7e89f37aa9 *./tests/data/a-adpcm_yam.wav 264248 ./tests/data/a-adpcm_yam.wav e92cec8c07913ffb91ad2b11f79cdc00 *./tests/data/adpcm_yam.vsynth.out.wav @@ -195,8 +195,8 @@ e48b800e2d9be6afcd430d4f08a34eb6 *./tests/data/adpcm_swf.vsynth.out.wav stddev:934.30 PSNR:36.91 bytes:1056768 c3382f03ce2efb5d475240d288a33898 *./tests/data/a-flac.flac 353368 ./tests/data/a-flac.flac -c4228df189aad9567a037727d0e763e4 *./tests/data/flac.vsynth.out.wav -stddev: 33.31 PSNR:65.87 bytes:1040384 +95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/flac.vsynth.out.wav +stddev: 0.00 PSNR:99.99 bytes:1056768 4435d87463cd6c5407bd88cca241ca56 *./tests/data/a-wmav1.asf 106004 ./tests/data/a-wmav1.asf stddev:12251.50 PSNR:14.56 bytes:1056768 diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/tests/ffserver.regression.ref b/src/plugins/thumbnailffmpeg/ffmpeg/tests/ffserver.regression.ref @@ -1,10 +1,10 @@ 18c4ba0e8e7adb781216e38de61c2e39 ff-test_h.avi -9818d41feb3e41efd5137c722f86f8f0 ff-test_l.avi +4f11d850f564af3359951b46ed1e571e ff-test_l.avi d976848a9e4d5d8fc2659e4841cdece5 ff-test.swf -7fa2bf4429c4bcd43bedc378ad89d799 ff-test_h.asf -0118b6fed8db6107bf50560fecaec6d3 ff-test_l.asf -942cdeafce330bf86ead504869d682da ff-test_h.rm -e84b0b64f41714b792451015223f7764 ff-test_l.rm -35d3332d7ef440273e8ebcfedeeae1ca ff-test.jpg -fe20235b8830e3a0e49a51dfcfb2a7a7 ff-test_small.jpg +37ccf79cb3a50fda99173e5ba4b44d55 ff-test_h.asf +3e2bff2fda1fe2ed334e639aa6839f0c ff-test_l.asf +60550d751dfa5172d878f7dd670e3aa4 ff-test_h.rm +6218946abd1c4af92f05a8a6208b1e1c ff-test_l.rm +e0dc91430660c619e97b5c82e0f398fc ff-test.jpg +84b9702e34b9e21a84bb29519fc1e3cc ff-test_small.jpg a22cc793b9f938cc05cd0c56ccf9423c ff-test.mjpg diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/tests/libav.regression.ref b/src/plugins/thumbnailffmpeg/ffmpeg/tests/libav.regression.ref @@ -12,10 +12,10 @@ bdb7484c68db722f66ba1630cf79844c *./tests/data/b-libav.mpg 447b005e527cf495ec13092e788f028d *./tests/data/b-libav.ts 471692 ./tests/data/b-libav.ts ./tests/data/b-libav.ts CRC=0xcc4948e1 -d6fdeb9f7083cc827f9510c6c4517dc0 *./tests/data/b-libav.swf +1b28a16652bb8ac528b33f7478ca18b6 *./tests/data/b-libav.swf 335771 ./tests/data/b-libav.swf ./tests/data/b-libav.swf CRC=0xe14e8847 -bbdd9a4904eceb530b1a9ae02c48d76f *./tests/data/b-libav.ffm +3dbacdc3fccb551f8ab54c32f648e7a8 *./tests/data/b-libav.ffm 380928 ./tests/data/b-libav.ffm ./tests/data/b-libav.ffm CRC=0x2b71a386 f8ad5bd78f4d012a8ce9570aa395ac54 *./tests/data/b-libav.flv @@ -93,7 +93,7 @@ ae3a23a7ea13c92a2909445ca8144dcd *./tests/data/b-libav.aif ./tests/data/b-libav.voc CRC=0x49972c8c 9268c90bd2623a5ab3c2a1a751826f69 *./tests/data/b-libav.ogg 14210 ./tests/data/b-libav.ogg -./tests/data/b-libav.ogg CRC=0x6bcbb966 +./tests/data/b-libav.ogg CRC=0x37a143ea ce356ce2708cb6033ab5d762da93cfd4 *./tests/data/b-libav-yuv420p.yuv 304128 ./tests/data/b-libav-yuv420p.yuv ce356ce2708cb6033ab5d762da93cfd4 *./tests/data/b-libav-yuv422p.yuv diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/tests/rotozoom.regression.ref b/src/plugins/thumbnailffmpeg/ffmpeg/tests/rotozoom.regression.ref @@ -181,10 +181,10 @@ efdae2746040dbc27be402b149556f1e *./tests/data/a-adpcm_qt.aiff 281184 ./tests/data/a-adpcm_qt.aiff 5a2084ad27674d5cf3bc2945061e7910 *./tests/data/adpcm_ima_qt.rotozoom.out.wav stddev:915.35 PSNR:37.09 bytes:1056768 -628d4789cf9ee16a756ac54b7fd8650d *./tests/data/a-adpcm_ms.wav +88a0c48c9bc6d50a84c408151c6a3d64 *./tests/data/a-adpcm_ms.wav 267320 ./tests/data/a-adpcm_ms.wav -91a84bb4f319a3a0bf0c0441b3d3a529 *./tests/data/adpcm_ms.rotozoom.out.wav -stddev:1050.18 PSNR:35.89 bytes:1054720 +d5f98f5136040be42232a34df92d61f2 *./tests/data/adpcm_ms.rotozoom.out.wav +stddev:1051.84 PSNR:35.88 bytes:1054720 ab11d9151644cbff27827b7e89f37aa9 *./tests/data/a-adpcm_yam.wav 264248 ./tests/data/a-adpcm_yam.wav e92cec8c07913ffb91ad2b11f79cdc00 *./tests/data/adpcm_yam.rotozoom.out.wav @@ -195,8 +195,8 @@ e48b800e2d9be6afcd430d4f08a34eb6 *./tests/data/adpcm_swf.rotozoom.out.wav stddev:934.30 PSNR:36.91 bytes:1056768 c3382f03ce2efb5d475240d288a33898 *./tests/data/a-flac.flac 353368 ./tests/data/a-flac.flac -c4228df189aad9567a037727d0e763e4 *./tests/data/flac.rotozoom.out.wav -stddev: 33.31 PSNR:65.87 bytes:1040384 +95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/flac.rotozoom.out.wav +stddev: 0.00 PSNR:99.99 bytes:1056768 4435d87463cd6c5407bd88cca241ca56 *./tests/data/a-wmav1.asf 106004 ./tests/data/a-wmav1.asf stddev:12251.50 PSNR:14.56 bytes:1056768 diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/tests/seek.regression.ref b/src/plugins/thumbnailffmpeg/ffmpeg/tests/seek.regression.ref @@ -2836,7 +2836,7 @@ ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st:-1 ts:1.894167 flags:1 ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st: 0 ts:0.788334 flags:0 -ret: 0 st: 1 dts:0.731429 pts:0.731429 pos:307200 size:209 flags:1 +ret: 0 st: 1 dts:0.783673 pts:0.783673 pos:319488 size:209 flags:1 ret: 0 st: 0 ts:-0.317499 flags:1 ret: 0 st: 0 dts:-0.040000 pts:0.000000 pos:8192 size:24795 flags:1 ret: 0 st: 1 ts:2.576668 flags:0 @@ -2844,7 +2844,7 @@ ret: 0 st: 1 dts:0.888163 pts:0.888163 pos:356352 size:209 flags:1 ret: 0 st: 1 ts:1.470835 flags:1 ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st:-1 ts:0.365002 flags:0 -ret: 0 st: 1 dts:0.313469 pts:0.313469 pos:147456 size:209 flags:1 +ret: 0 st: 1 dts:0.339592 pts:0.339592 pos:159744 size:209 flags:1 ret: 0 st:-1 ts:-0.740831 flags:1 ret: 0 st: 0 dts:-0.040000 pts:0.000000 pos:8192 size:24795 flags:1 ret: 0 st: 0 ts:2.153336 flags:0 @@ -2858,7 +2858,7 @@ ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st:-1 ts:1.730004 flags:0 ret: 0 st: 1 dts:0.888163 pts:0.888163 pos:356352 size:209 flags:1 ret: 0 st:-1 ts:0.624171 flags:1 -ret: 0 st: 1 dts:0.574694 pts:0.574694 pos:253952 size:209 flags:1 +ret: 0 st: 1 dts:0.600816 pts:0.600816 pos:266240 size:209 flags:1 ret: 0 st: 0 ts:-0.481662 flags:0 ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st: 0 ts:2.412505 flags:1 @@ -2872,7 +2872,7 @@ ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st:-1 ts:1.989173 flags:1 ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st: 0 ts:0.883340 flags:0 -ret: 0 st: 1 dts:0.809796 pts:0.809796 pos:331776 size:209 flags:1 +ret: 0 st: 1 dts:0.862041 pts:0.862041 pos:344064 size:209 flags:1 ret: 0 st: 0 ts:-0.222493 flags:1 ret: 0 st: 0 dts:-0.040000 pts:0.000000 pos:8192 size:24795 flags:1 ret: 0 st: 1 ts:2.671674 flags:0 @@ -2880,7 +2880,7 @@ ret: 0 st: 1 dts:0.888163 pts:0.888163 pos:356352 size:209 flags:1 ret: 0 st: 1 ts:1.565841 flags:1 ret: 0 st: 1 dts:0.940408 pts:0.940408 pos:380928 size:209 flags:1 ret: 0 st:-1 ts:0.460008 flags:0 -ret: 0 st: 0 dts:0.400000 pts:0.440000 pos:172032 size:12546 flags:0 +ret: 0 st: 1 dts:0.444082 pts:0.444082 pos:208896 size:209 flags:1 ret: 0 st:-1 ts:-0.645825 flags:1 ret: 0 st: 0 dts:-0.040000 pts:0.000000 pos:8192 size:24795 flags:1 ---------------- @@ -3481,7 +3481,7 @@ ret:-1 st:-1 ts:0.460008 flags:0 ret:-1 st:-1 ts:-0.645825 flags:1 ---------------- tests/data/b-libav.ts -ret: 0 st: 0 dts:0.000000 pts:-102481911520608.625000 pos:-1 size:24921 flags:1 +ret: 0 st: 0 dts:-102481911520608.625000 pts:-102481911520608.625000 pos:-1 size:24921 flags:1 ret: 0 st:-1 ts:-1.000000 flags:0 ret: 0 st: 0 dts:0.000000 pts:-102481911520608.625000 pos:-1 size:22036 flags:1 ret: 0 st:-1 ts:1.894167 flags:1 diff --git a/src/plugins/thumbnailffmpeg/ffmpeg/tools/trasher.c b/src/plugins/thumbnailffmpeg/ffmpeg/tools/trasher.c @@ -41,7 +41,7 @@ int main(int argc, char** argv) count= atoi(argv[2]); maxburst= atoi(argv[3]); - srand (time (0)); + srandom (time (0)); fseek(f, 0, SEEK_END); length= ftell(f);